├── .browserslistrc ├── .eslintrc.js ├── .github └── workflows │ ├── Build.yml │ └── Release.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── babel.config.js ├── build └── config.gypi ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── openbom.ico ├── src ├── App.vue ├── assets │ ├── ad.jpg │ ├── cadence.png │ ├── jlc.jpg │ ├── jlc.png │ └── logo.png ├── background.js ├── components │ ├── adConfig.vue │ ├── adFpConfig.vue │ ├── adLibraryConfig.vue │ ├── bomTable.vue │ ├── cadenceConfig.vue │ ├── dbConfig.vue │ ├── itemViewer.vue │ ├── jlc2bom.vue │ ├── pdfViewer.vue │ ├── products.js │ └── table.vue ├── db │ ├── db.js │ ├── entity │ │ ├── bom │ │ │ ├── Cap.js │ │ │ ├── Connector.js │ │ │ ├── Diode.js │ │ │ └── Res.js │ │ └── jlc │ │ │ ├── Cap.js │ │ │ ├── Connector.js │ │ │ ├── Diode.js │ │ │ └── Res.js │ └── search.js ├── main.js ├── plugins │ └── element.js ├── router │ └── index.js ├── store │ └── index.js └── views │ ├── Bom.vue │ ├── Config.vue │ └── Home.vue └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | 'extends': [ 7 | 'plugin:vue/essential', 8 | 'eslint:recommended' 9 | ], 10 | parserOptions: { 11 | parser: 'babel-eslint' 12 | }, 13 | rules: { 14 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 15 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/Build.yml: -------------------------------------------------------------------------------- 1 | name: Build CI 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - README.md 7 | - LICENSE.txt 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: windows-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [12.x] 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | - uses: actions/cache@v1 25 | with: 26 | path: ~\AppData\Roaming\npm-cache 27 | key: ${{ runner.os }}-node-${{ hashFiles('**\package-lock.json') }} 28 | restore-keys: | 29 | ${{ runner.os }}-node- 30 | - run: | 31 | npm install 32 | - run: npm run lint 33 | - run: npm run electron:build 34 | env: 35 | CI: true 36 | GH_TOKEN: ${{ secrets.github_token }} -------------------------------------------------------------------------------- /.github/workflows/Release.yml: -------------------------------------------------------------------------------- 1 | name: Release CI 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: windows-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [12.x] 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - uses: actions/cache@v1 24 | with: 25 | path: ~\AppData\Roaming\npm-cache 26 | key: ${{ runner.os }}-node-${{ hashFiles('**\package-lock.json') }} 27 | restore-keys: | 28 | ${{ runner.os }}-node- 29 | - run: | 30 | npm install 31 | - run: npm run lint 32 | - run: npm run electron:build 33 | env: 34 | CI: true 35 | GH_TOKEN: ${{ secrets.github_token }} 36 | - name: Create Release 37 | id: create_release 38 | uses: actions/create-release@v1 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.github_token }} 41 | with: 42 | tag_name: ${{ github.ref }} 43 | release_name: Release ${{ github.ref }} 44 | draft: false 45 | prerelease: false 46 | - name: Upload Release Asset 47 | id: upload-release-asset1 48 | uses: actions/upload-release-asset@v1 49 | env: 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | with: 52 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 53 | asset_path: ./dist_electron/OpenBom.exe 54 | asset_name: OpenBom.exe 55 | asset_content_type: application/vnd.microsoft.portable-executable 56 | - name: Upload latest yml 57 | id: upload-release-asset2 58 | uses: actions/upload-release-asset@v1 59 | env: 60 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 61 | with: 62 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 63 | asset_path: ./dist_electron/latest.yml 64 | asset_name: latest.yml 65 | asset_content_type: application/x-yaml -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | 25 | #Electron-builder output 26 | /dist_electron -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2020 WhyEngineer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openbom 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /build/config.gypi: -------------------------------------------------------------------------------- 1 | # Do not edit. File was generated by node-gyp's "configure" step 2 | { 3 | "target_defaults": { 4 | "cflags": [], 5 | "default_configuration": "Release", 6 | "defines": [], 7 | "include_dirs": [], 8 | "libraries": [], 9 | "msbuild_toolset": "v141", 10 | "msvs_windows_target_platform_version": "10.0.17763.0" 11 | }, 12 | "variables": { 13 | "asan": 0, 14 | "build_v8_with_gn": "false", 15 | "coverage": "false", 16 | "debug_nghttp2": "false", 17 | "enable_lto": "false", 18 | "enable_pgo_generate": "false", 19 | "enable_pgo_use": "false", 20 | "force_dynamic_crt": 0, 21 | "host_arch": "x64", 22 | "icu_data_in": "..\\..\\deps/icu-small\\source/data/in\\icudt64l.dat", 23 | "icu_default_data": "", 24 | "icu_endianness": "l", 25 | "icu_gyp_path": "tools/icu/icu-generic.gyp", 26 | "icu_locales": "en,root", 27 | "icu_path": "deps/icu-small", 28 | "icu_small": "true", 29 | "icu_ver_major": "64", 30 | "is_debug": 0, 31 | "napi_build_version": "5", 32 | "nasm_version": "2.14", 33 | "node_byteorder": "little", 34 | "node_debug_lib": "false", 35 | "node_enable_d8": "false", 36 | "node_install_npm": "true", 37 | "node_module_version": 72, 38 | "node_no_browser_globals": "false", 39 | "node_prefix": "/usr/local", 40 | "node_release_urlbase": "https://nodejs.org/download/release/", 41 | "node_report": "true", 42 | "node_shared": "false", 43 | "node_shared_cares": "false", 44 | "node_shared_http_parser": "false", 45 | "node_shared_libuv": "false", 46 | "node_shared_nghttp2": "false", 47 | "node_shared_openssl": "false", 48 | "node_shared_zlib": "false", 49 | "node_tag": "", 50 | "node_target_type": "executable", 51 | "node_use_bundled_v8": "true", 52 | "node_use_dtrace": "false", 53 | "node_use_etw": "true", 54 | "node_use_large_pages": "false", 55 | "node_use_large_pages_script_lld": "false", 56 | "node_use_node_code_cache": "true", 57 | "node_use_node_snapshot": "true", 58 | "node_use_openssl": "true", 59 | "node_use_v8_platform": "true", 60 | "node_with_ltcg": "true", 61 | "node_without_node_options": "false", 62 | "openssl_fips": "", 63 | "openssl_is_fips": "false", 64 | "shlib_suffix": "so.72", 65 | "target_arch": "x64", 66 | "v8_enable_gdbjit": 0, 67 | "v8_enable_i18n_support": 1, 68 | "v8_enable_inspector": 1, 69 | "v8_no_strict_aliasing": 1, 70 | "v8_optimized_debug": 1, 71 | "v8_promise_internal_field_count": 1, 72 | "v8_random_seed": 0, 73 | "v8_trace_maps": 0, 74 | "v8_use_siphash": 1, 75 | "v8_use_snapshot": 1, 76 | "want_separate_host_toolset": 0, 77 | "nodedir": "C:\\Users\\frank\\.electron-gyp\\9.3.4", 78 | "standalone_static_library": 1, 79 | "msbuild_path": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\MSBuild\\15.0\\Bin\\MSBuild.exe", 80 | "access": "", 81 | "allow_same_version": "", 82 | "also": "", 83 | "always_auth": "", 84 | "audit": "true", 85 | "audit_level": "low", 86 | "auth_type": "legacy", 87 | "before": "", 88 | "bin_links": "true", 89 | "browser": "", 90 | "build_from_source": "true", 91 | "ca": "", 92 | "cache": "C:\\Users\\frank\\AppData\\Roaming\\npm-cache", 93 | "cache_lock_retries": "10", 94 | "cache_lock_stale": "60000", 95 | "cache_lock_wait": "10000", 96 | "cache_max": "Infinity", 97 | "cache_min": "10", 98 | "cert": "", 99 | "cidr": "", 100 | "color": "true", 101 | "commit_hooks": "true", 102 | "depth": "Infinity", 103 | "description": "true", 104 | "dev": "", 105 | "disturl": "https://electronjs.org/headers", 106 | "dry_run": "", 107 | "editor": "notepad.exe", 108 | "engine_strict": "", 109 | "fallback_to_build": "true", 110 | "fetch_retries": "2", 111 | "fetch_retry_factor": "10", 112 | "fetch_retry_maxtimeout": "60000", 113 | "fetch_retry_mintimeout": "10000", 114 | "force": "", 115 | "format_package_lock": "true", 116 | "fund": "true", 117 | "git": "git", 118 | "git_tag_version": "true", 119 | "global": "", 120 | "globalconfig": "C:\\Users\\frank\\AppData\\Roaming\\npm\\etc\\npmrc", 121 | "globalignorefile": "C:\\Users\\frank\\AppData\\Roaming\\npm\\etc\\npmignore", 122 | "global_style": "", 123 | "group": "", 124 | "ham_it_up": "", 125 | "heading": "npm", 126 | "https_proxy": "", 127 | "if_present": "", 128 | "ignore_prepublish": "", 129 | "ignore_scripts": "", 130 | "init_author_email": "", 131 | "init_author_name": "", 132 | "init_author_url": "", 133 | "init_license": "ISC", 134 | "init_module": "C:\\Users\\frank\\.npm-init.js", 135 | "init_version": "1.0.0", 136 | "json": "", 137 | "key": "", 138 | "legacy_bundling": "", 139 | "link": "", 140 | "local_address": "", 141 | "logs_max": "10", 142 | "long": "", 143 | "maxsockets": "50", 144 | "message": "%s", 145 | "metrics_registry": "https://registry.npm.taobao.org/", 146 | "node_gyp": "C:\\Users\\frank\\AppData\\Roaming\\npm\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js", 147 | "node_options": "", 148 | "node_version": "12.16.1", 149 | "offline": "", 150 | "onload_script": "", 151 | "only": "", 152 | "optional": "true", 153 | "otp": "", 154 | "package_lock": "true", 155 | "package_lock_only": "", 156 | "parseable": "", 157 | "platform": "win32", 158 | "prefer_offline": "", 159 | "prefer_online": "", 160 | "prefix": "C:\\Users\\frank\\AppData\\Roaming\\npm", 161 | "preid": "", 162 | "production": "", 163 | "progress": "true", 164 | "read_only": "", 165 | "rebuild_bundle": "true", 166 | "registry": "https://registry.npm.taobao.org/", 167 | "rollback": "true", 168 | "runtime": "electron", 169 | "save": "true", 170 | "save_bundle": "", 171 | "save_dev": "", 172 | "save_exact": "", 173 | "save_optional": "", 174 | "save_prefix": "^", 175 | "save_prod": "", 176 | "scope": "", 177 | "scripts_prepend_node_path": "warn-only", 178 | "script_shell": "", 179 | "searchexclude": "", 180 | "searchlimit": "20", 181 | "searchopts": "", 182 | "searchstaleness": "900", 183 | "send_metrics": "", 184 | "shell": "C:\\WINDOWS\\system32\\cmd.exe", 185 | "shrinkwrap": "true", 186 | "sign_git_commit": "", 187 | "sign_git_tag": "", 188 | "sso_poll_frequency": "500", 189 | "sso_type": "oauth", 190 | "strict_ssl": "true", 191 | "tag": "latest", 192 | "tag_version_prefix": "v", 193 | "target": "9.3.4", 194 | "target_libc": "unknown", 195 | "target_platform": "win32", 196 | "timing": "", 197 | "tmp": "C:\\Users\\frank\\AppData\\Local\\Temp", 198 | "umask": "0000", 199 | "unicode": "", 200 | "unsafe_perm": "true", 201 | "update_binary": "true", 202 | "update_notifier": "true", 203 | "usage": "", 204 | "user": "", 205 | "userconfig": "C:\\Users\\frank\\.npmrc", 206 | "user_agent": "npm/6.14.8 node/v12.16.1 win32 x64", 207 | "version": "", 208 | "versions": "", 209 | "viewer": "browser" 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openbom", 3 | "version": "0.2.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint", 9 | "electron:build": "vue-cli-service electron:build", 10 | "electron:serve": "vue-cli-service electron:serve", 11 | "postinstall": "electron-builder install-app-deps", 12 | "postuninstall": "electron-builder install-app-deps" 13 | }, 14 | "main": "background.js", 15 | "dependencies": { 16 | "core-js": "^3.6.5", 17 | "electron-log": "^4.3.0", 18 | "electron-pdf-window": "^1.0.12", 19 | "electron-store": "^6.0.1", 20 | "element-ui": "^2.4.5", 21 | "flexsearch": "^0.6.32", 22 | "mysql": "^2.18.1", 23 | "sqlite3": "^5.0.0", 24 | "typeorm": "^0.2.29", 25 | "vue": "^2.6.11", 26 | "vue-dragscroll": "^2.1.0", 27 | "vue-pdf": "^4.2.0", 28 | "vue-router": "^3.2.0", 29 | "vuex": "^3.4.0" 30 | }, 31 | "devDependencies": { 32 | "@vue/cli-plugin-babel": "~4.5.0", 33 | "@vue/cli-plugin-eslint": "~4.5.0", 34 | "@vue/cli-plugin-router": "~4.5.0", 35 | "@vue/cli-plugin-vuex": "~4.5.0", 36 | "@vue/cli-service": "~4.5.0", 37 | "babel-eslint": "^10.1.0", 38 | "electron": "^9.0.0", 39 | "electron-devtools-installer": "^3.1.0", 40 | "eslint": "^6.7.2", 41 | "eslint-plugin-vue": "^6.2.2", 42 | "vue-cli-plugin-electron-builder": "~2.0.0-rc.5", 43 | "vue-cli-plugin-element": "~1.0.1", 44 | "vue-template-compiler": "^2.6.11" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whyengineer/OpenBOM/cd776ebef9fdc759236642e028f5228107cc91db/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | OpenBom-WhyEngineer 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /public/openbom.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whyengineer/OpenBOM/cd776ebef9fdc759236642e028f5228107cc91db/public/openbom.ico -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 40 | 41 | 55 | -------------------------------------------------------------------------------- /src/assets/ad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whyengineer/OpenBOM/cd776ebef9fdc759236642e028f5228107cc91db/src/assets/ad.jpg -------------------------------------------------------------------------------- /src/assets/cadence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whyengineer/OpenBOM/cd776ebef9fdc759236642e028f5228107cc91db/src/assets/cadence.png -------------------------------------------------------------------------------- /src/assets/jlc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whyengineer/OpenBOM/cd776ebef9fdc759236642e028f5228107cc91db/src/assets/jlc.jpg -------------------------------------------------------------------------------- /src/assets/jlc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whyengineer/OpenBOM/cd776ebef9fdc759236642e028f5228107cc91db/src/assets/jlc.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whyengineer/OpenBOM/cd776ebef9fdc759236642e028f5228107cc91db/src/assets/logo.png -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import { app, protocol, BrowserWindow } from 'electron' 4 | import { createProtocol } from 'vue-cli-plugin-electron-builder/lib' 5 | import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer' 6 | import db from './db/db' 7 | const isDevelopment = process.env.NODE_ENV !== 'production' 8 | 9 | // Scheme must be registered before the app is ready 10 | protocol.registerSchemesAsPrivileged([ 11 | { scheme: 'app', privileges: { secure: true, standard: true } } 12 | ]) 13 | 14 | async function createWindow() { 15 | // Create the browser window. 16 | const win = new BrowserWindow({ 17 | width: 1200, 18 | height: 600, 19 | minWidth:1000, 20 | title:'OpenBom-WhyEngineer', 21 | webPreferences: { 22 | // Use pluginOptions.nodeIntegration, leave this alone 23 | // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info 24 | nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION 25 | }, 26 | // eslint-disable-next-line no-undef 27 | icon: `${__static}/openbom.ico` 28 | }) 29 | const database= new db(win) 30 | database.connect(true) 31 | if (process.env.WEBPACK_DEV_SERVER_URL) { 32 | // Load the url of the dev server if in development mode 33 | await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL) 34 | if (!process.env.IS_TEST) win.webContents.openDevTools() 35 | } else { 36 | createProtocol('app') 37 | // Load the index.html when not in development 38 | win.loadURL('app://./index.html') 39 | } 40 | } 41 | 42 | // Quit when all windows are closed. 43 | app.on('window-all-closed', () => { 44 | // On macOS it is common for applications and their menu bar 45 | // to stay active until the user quits explicitly with Cmd + Q 46 | if (process.platform !== 'darwin') { 47 | app.quit() 48 | } 49 | }) 50 | 51 | app.on('activate', () => { 52 | // On macOS it's common to re-create a window in the app when the 53 | // dock icon is clicked and there are no other windows open. 54 | if (BrowserWindow.getAllWindows().length === 0) createWindow() 55 | }) 56 | 57 | // This method will be called when Electron has finished 58 | // initialization and is ready to create browser windows. 59 | // Some APIs can only be used after this event occurs. 60 | app.on('ready', async () => { 61 | if (isDevelopment && !process.env.IS_TEST) { 62 | // Install Vue Devtools 63 | try { 64 | await installExtension(VUEJS_DEVTOOLS) 65 | } catch (e) { 66 | console.error('Vue Devtools failed to install:', e.toString()) 67 | } 68 | } 69 | createWindow() 70 | }) 71 | 72 | // Exit cleanly on request from parent process in development mode. 73 | if (isDevelopment) { 74 | if (process.platform === 'win32') { 75 | process.on('message', (data) => { 76 | if (data === 'graceful-exit') { 77 | app.quit() 78 | } 79 | }) 80 | } else { 81 | process.on('SIGTERM', () => { 82 | app.quit() 83 | }) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/components/adConfig.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/adFpConfig.vue: -------------------------------------------------------------------------------- 1 | 76 | 77 | 124 | 125 | -------------------------------------------------------------------------------- /src/components/adLibraryConfig.vue: -------------------------------------------------------------------------------- 1 | 76 | 77 | 124 | 125 | -------------------------------------------------------------------------------- /src/components/bomTable.vue: -------------------------------------------------------------------------------- 1 | 155 | 156 | 345 | 346 | 347 | 376 | -------------------------------------------------------------------------------- /src/components/cadenceConfig.vue: -------------------------------------------------------------------------------- 1 | 76 | 77 | 129 | 130 | -------------------------------------------------------------------------------- /src/components/dbConfig.vue: -------------------------------------------------------------------------------- 1 | 102 | 103 | 154 | 155 | -------------------------------------------------------------------------------- /src/components/itemViewer.vue: -------------------------------------------------------------------------------- 1 | 37 | 60 | -------------------------------------------------------------------------------- /src/components/jlc2bom.vue: -------------------------------------------------------------------------------- 1 | 156 | 358 | -------------------------------------------------------------------------------- /src/components/pdfViewer.vue: -------------------------------------------------------------------------------- 1 | 58 | 59 | 125 | -------------------------------------------------------------------------------- /src/components/products.js: -------------------------------------------------------------------------------- 1 | export default 2 | [ 3 | { 4 | value: "cap", 5 | label: "CAP", 6 | children: [ 7 | { 8 | value: "贴片电容", 9 | label: "贴片电容", 10 | }, 11 | { 12 | value: "牛角型电解电容器", 13 | label: "牛角型电解电容器", 14 | }, 15 | { 16 | value: "钽电容", 17 | label: "钽电容", 18 | }, 19 | { 20 | value: "贴片型铝电解电容", 21 | label: "贴片型铝电解电容", 22 | }, 23 | { 24 | value: "引线型铝电解电容", 25 | label: "引线型铝电解电容", 26 | }, 27 | { 28 | value: "螺栓型铝电解电容", 29 | label: "螺栓型铝电解电容", 30 | }, 31 | { 32 | value: "直插瓷片电容", 33 | label: "直插瓷片电容", 34 | }, 35 | { 36 | value: "直插独石电容", 37 | label: "直插独石电容", 38 | }, 39 | { 40 | value: "安规电容", 41 | label: "安规电容", 42 | }, 43 | { 44 | value: "可调电容", 45 | label: "可调电容", 46 | }, 47 | { 48 | value: "CBB电容(聚丙烯)", 49 | label: "CBB电容(聚丙烯)", 50 | }, 51 | { 52 | value: "校正电容", 53 | label: "校正电容", 54 | }, 55 | { 56 | value: "固态电解电容", 57 | label: "固态电解电容", 58 | }, 59 | { 60 | value: "超级电容器", 61 | label: "超级电容器", 62 | }, 63 | { 64 | value: "CL21电容", 65 | label: "CL21电容", 66 | }, 67 | { 68 | value: "聚酯薄膜电容", 69 | label: "聚酯薄膜电容", 70 | }, 71 | { 72 | value: "氧化铌电容", 73 | label: "氧化铌电容", 74 | }, 75 | { 76 | value: "电容器网络,阵列", 77 | label: "电容器网络,阵列", 78 | }, 79 | ], 80 | }, 81 | { 82 | value:'res', 83 | label:'RES', 84 | children:[ 85 | { 86 | value:'贴片电阻', 87 | label:'贴片电阻' 88 | }, 89 | { 90 | value:'贴片高精密、低温漂电阻', 91 | label:'贴片高精密、低温漂电阻' 92 | }, 93 | { 94 | value:'高功率贴片电阻', 95 | label:'贴片低阻值采样电阻', 96 | }, 97 | { 98 | value:'直插低阻值采样电阻', 99 | label:'直插低阻值采样电阻' 100 | }, 101 | { 102 | value:'压敏电阻', 103 | label:'压敏电阻' 104 | }, 105 | { 106 | value:'网络排阻', 107 | label:'网络排阻' 108 | }, 109 | { 110 | value:'MELF 电阻', 111 | label:'MELF 电阻' 112 | }, 113 | { 114 | value:'NTC 热敏电阻', 115 | label:'NTC 热敏电阻' 116 | }, 117 | { 118 | value:'PTC 热敏电阻', 119 | label:'PTC 热敏电阻' 120 | }, 121 | { 122 | value:'金属膜电阻', 123 | label:'金属膜电阻' 124 | }, 125 | { 126 | value:'金属氧化膜电阻', 127 | label:'金属氧化膜电阻' 128 | }, 129 | { 130 | value:'碳膜电阻', 131 | label:'碳膜电阻' 132 | }, 133 | { 134 | value:'精密可调电阻', 135 | label:'精密可调电阻' 136 | }, 137 | { 138 | value:'可调电阻', 139 | label:'可调电阻' 140 | }, 141 | { 142 | value:'电位器、其他可调电阻', 143 | label:'电位器、其他可调电阻' 144 | }, 145 | { 146 | value:'绕线电阻', 147 | label:'绕线电阻' 148 | }, 149 | { 150 | value:'保险电阻', 151 | label:'保险电阻' 152 | }, 153 | { 154 | value:'TO封装平面功率电阻', 155 | label:'TO封装平面功率电阻' 156 | }, 157 | { 158 | value:'高压电阻', 159 | label:'高压电阻' 160 | }, 161 | { 162 | value:'光敏电阻', 163 | label:'光敏电阻' 164 | }, 165 | { 166 | value:'金属玻璃釉电阻', 167 | label:'金属玻璃釉电阻' 168 | }, 169 | { 170 | value:'水泥电阻', 171 | label:'水泥电阻' 172 | }, 173 | { 174 | value:'LED灯条电阻', 175 | label:'LED灯条电阻' 176 | }, 177 | { 178 | value:'铝壳电阻', 179 | label:'铝壳电阻' 180 | }, 181 | { 182 | value:'分流器', 183 | label:'分流器' 184 | } 185 | ] 186 | }, 187 | { 188 | value:'diode', 189 | label:'DIODE', 190 | children:[ 191 | { 192 | value:'稳压二极管', 193 | label:'稳压二极管' 194 | }, 195 | { 196 | value:'通用二极管', 197 | label:'通用二极管' 198 | }, 199 | { 200 | value:'快恢复二极管', 201 | label:'快恢复二极管' 202 | }, 203 | { 204 | value:'超快恢复二极管', 205 | label:'超快恢复二极管' 206 | }, 207 | { 208 | value:'肖特基二极管', 209 | label:'肖特基二极管' 210 | }, 211 | { 212 | value:'整流桥', 213 | label:'整流桥' 214 | }, 215 | { 216 | value:'开关二极管', 217 | label:'开关二极管' 218 | }, 219 | { 220 | value:'触发二极管', 221 | label:'触发二极管' 222 | }, 223 | { 224 | value:'TVS二极管', 225 | label:'TVS二极管' 226 | }, 227 | { 228 | value:'放电管', 229 | label:'放电管' 230 | }, 231 | { 232 | value:'ESD二极管', 233 | label:'ESD二极管' 234 | }, 235 | { 236 | value:'雪崩二极管', 237 | label:'雪崩二极管' 238 | }, 239 | { 240 | value:'高效率二极管', 241 | label:'高效率二极管' 242 | }, 243 | { 244 | value:'变容二极管', 245 | label:'变容二极管' 246 | }, 247 | { 248 | value:'恒流二极管', 249 | label:'恒流二极管' 250 | }, 251 | ] 252 | }, 253 | { 254 | value:'connector', 255 | label:'CONNECTOR', 256 | children:[ 257 | { 258 | value:'预售连接器', 259 | label:'预售连接器' 260 | }, 261 | { 262 | value:'排针排母', 263 | label:'排针排母' 264 | }, 265 | { 266 | value:'线对板/线对线连接器', 267 | label:'线对板/线对线连接器' 268 | }, 269 | { 270 | value:'USB连接器', 271 | label:'USB连接器' 272 | }, 273 | { 274 | value:'IDC连接器(牛角/简牛)', 275 | label:'IDC连接器(牛角/简牛)' 276 | }, 277 | { 278 | value:'FFC,FPC连接器', 279 | label:'FFC,FPC连接器' 280 | }, 281 | { 282 | value:'插拔式接线端子', 283 | label:'插拔式接线端子' 284 | }, 285 | { 286 | value:'螺钉式接线端子', 287 | label:'螺钉式接线端子' 288 | }, 289 | { 290 | value:'弹簧式接线端子', 291 | label:'弹簧式接线端子' 292 | }, 293 | { 294 | value:'栅栏式接线端子', 295 | label:'栅栏式接线端子' 296 | }, 297 | { 298 | value:'以太网连接器 (RJ45 RJ11)', 299 | label:'以太网连接器 (RJ45 RJ11)' 300 | }, 301 | { 302 | value:'D-Sub连接器', 303 | label:'D-Sub连接器' 304 | }, 305 | { 306 | value:'音频与视频连接器', 307 | label:'音频与视频连接器' 308 | }, 309 | { 310 | value:'AC/DC电源插座', 311 | label:'AC/DC电源插座' 312 | }, 313 | { 314 | value:'IC插座', 315 | label:'IC插座' 316 | }, 317 | { 318 | value:'卡座连接器', 319 | label:'卡座连接器' 320 | }, 321 | { 322 | value:'RF同轴连接器(天线座)', 323 | label:'RF同轴连接器(天线座)' 324 | }, 325 | { 326 | value:'板对板连接器', 327 | label:'板对板连接器' 328 | }, 329 | { 330 | value:'压接端子', 331 | label:'压接端子' 332 | }, 333 | { 334 | value:'圆形连接器', 335 | label:'圆形连接器' 336 | }, 337 | { 338 | value:'轨道式接线端子', 339 | label:'轨道式接线端子' 340 | }, 341 | { 342 | value:'“金手指”连接器', 343 | label:'“金手指”连接器' 344 | }, 345 | { 346 | value:'背板连接器', 347 | label:'背板连接器' 348 | }, 349 | { 350 | value:'电源连接器 ', 351 | label:'电源连接器 ' 352 | }, 353 | { 354 | value:'照明连接器', 355 | label:'照明连接器' 356 | }, 357 | { 358 | value:'香蕉和尖头连接器', 359 | label:'香蕉和尖头连接器' 360 | }, 361 | { 362 | value:'隔灯柱(间隔柱)', 363 | label:'隔灯柱(间隔柱)' 364 | }, 365 | { 366 | value:'测试夹/鳄鱼夹', 367 | label:'测试夹/鳄鱼夹' 368 | }, 369 | { 370 | value:'短路帽', 371 | label:'短路帽' 372 | }, 373 | { 374 | value:'测试点/测试环', 375 | label:'测试点/测试环' 376 | }, 377 | { 378 | value:'压线端子胶壳', 379 | label:'压线端子胶壳' 380 | }, 381 | { 382 | value:'连接器 - 外壳', 383 | label:'连接器 - 外壳' 384 | }, 385 | { 386 | value:'连接器 - 附件', 387 | label:'连接器 - 附件' 388 | }, 389 | ] 390 | } 391 | ] 392 | -------------------------------------------------------------------------------- /src/components/table.vue: -------------------------------------------------------------------------------- 1 | 142 | 143 | 321 | 322 | 323 | 352 | -------------------------------------------------------------------------------- /src/db/db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import { getRepository, createConnection } from "typeorm"; 3 | import { Cap } from './entity/jlc/Cap'; 4 | import { Res } from './entity/jlc/Res'; 5 | import { Diode } from './entity/jlc/Diode'; 6 | import { Connector } from './entity/jlc/Connector'; 7 | import { ipcMain } from 'electron'; 8 | import log from 'electron-log'; 9 | import search from './search'; 10 | import { BomCap } from './entity/bom/Cap'; 11 | import { BomRes } from './entity/bom/Res'; 12 | import { BomDiode } from './entity/bom/Diode'; 13 | import { BomConnector } from './entity/bom/Connector'; 14 | import Store from 'electron-store'; 15 | 16 | const store = new Store(); 17 | 18 | export default class Db { 19 | constructor(win, logEnable = true) { 20 | this.win = win; 21 | this.log = logEnable; 22 | this.repo = {} 23 | this.connected = { 24 | jlc: false, 25 | bom: false, 26 | } 27 | this.lastErr = { 28 | jlc: '', 29 | bom: '' 30 | } 31 | this.search = new search(this.repo) 32 | // this.repo={ 33 | // jlc:this.jlc 34 | // } 35 | // this.jlc = getConnection('jlc'); 36 | // this.bom = getConnection('bom'); 37 | ipcMain.on('dbConnecStatus', (evt, db) => { 38 | evt.returnValue = { 39 | status:this.connected[db], 40 | msg:this.lastErr[db] 41 | } 42 | }) 43 | ipcMain.on('search', (evt, val) => { 44 | let ret 45 | if (this.connected[val.db]) 46 | ret = this.search.search(val.db, val.column, val.type, val.msg) 47 | else 48 | ret = [] 49 | let parseRet = [] 50 | for (let i in ret) { 51 | parseRet.push(this.parseJlc(ret[i])) 52 | } 53 | evt.reply(val.event, parseRet) 54 | }) 55 | ipcMain.on('dbUpdateItem', (evt, db) => { 56 | if (this.connected[db.db]) { 57 | this.repo[db.db][db.column].update({pn:db.value.pn},db.value).then(() => { 58 | let ret = db 59 | ret.status = true 60 | evt.reply(db.event, ret) 61 | }).catch(err => { 62 | log.error(err) 63 | let ret = db 64 | ret.status = false 65 | ret.err = err.message 66 | evt.reply(db.event, ret) 67 | }) 68 | } else { 69 | let ret = db 70 | ret.status = false 71 | ret.err = `${db.db} doesn't connect` 72 | evt.reply(db.event, ret) 73 | } 74 | 75 | }) 76 | ipcMain.on('dbDeleteItem', (evt, db) => { 77 | if (this.connected[db.db]) { 78 | this.repo[db.db][db.column].delete(db.value.id).then(() => { 79 | let ret = db 80 | ret.status = true 81 | evt.reply(db.event, ret) 82 | }).catch(err => { 83 | log.error(err) 84 | let ret = db 85 | ret.status = false 86 | ret.err = err.message 87 | evt.reply(db.event, ret) 88 | }) 89 | } else { 90 | let ret = db 91 | ret.status = false 92 | ret.err = `${db.db} doesn't connect` 93 | evt.reply(db.event, ret) 94 | } 95 | 96 | }) 97 | ipcMain.on('dbCreateItem', (evt, db) => { 98 | if (this.connected[db.db]) { 99 | this.repo[db.db][db.column].save(db.value).then(() => { 100 | let ret = db 101 | ret.status = true 102 | evt.reply(db.event, ret) 103 | }).catch(err => { 104 | log.error(err) 105 | let ret = db 106 | ret.status = false 107 | ret.err = err.message 108 | evt.reply(db.event, ret) 109 | }) 110 | } else { 111 | let ret = db 112 | ret.status = false 113 | ret.err = `${db.db} doesn't connect` 114 | evt.reply(db.event, ret) 115 | } 116 | 117 | }) 118 | ipcMain.on('dbGetCount', (evt, db) => { 119 | if (this.connected[db.db]) { 120 | if((db.buildSearch !=undefined)&&(db.buildSearch)){ 121 | this.search.buildSearch(db.db, db.column, db.type, () => { 122 | log.info("build search ok"); 123 | }) 124 | } 125 | this.repo[db.db][db.column].count(db.option != undefined ? db.option : '').then(val => { 126 | let ret = db 127 | ret.count = val 128 | evt.reply(db.event, ret) 129 | }).catch(err => { 130 | log.error(err) 131 | }) 132 | } else { 133 | let ret = db 134 | ret.count = 0 135 | evt.reply(db.event, ret) 136 | } 137 | }) 138 | ipcMain.on('getData', (evt, db) => { 139 | if (this.connected[db.db]) { 140 | this.repo[db.db][db.column].find({ 141 | skip: db.start, 142 | take: db.end - db.start, 143 | where: db.where != undefined ? db.where : '' 144 | }).then((val) => { 145 | let ret = db 146 | ret.data = [] 147 | for (let i in val) { 148 | if(db.db=='jlc') 149 | ret.data.push(this.parseJlc(val[i], db.column)) 150 | else 151 | ret.data.push(val[i]) 152 | } 153 | evt.reply(db.event, ret) 154 | 155 | }).catch(err => { 156 | log.error(err) 157 | }) 158 | } else { 159 | let ret = db 160 | ret.data = [] 161 | evt.reply(db.event, ret) 162 | } 163 | 164 | }) 165 | } 166 | parseJlc(val, g) { 167 | var a = { 168 | pn: '', 169 | vendor: '', 170 | vendorPn: '', 171 | vendorUrl: '', 172 | value: '', 173 | prices: [], 174 | imgs: [], 175 | symbolUrl: '', 176 | footprint: '', 177 | fpUrl: '', 178 | desc: '', 179 | datasheet: '', 180 | g: 'cap', 181 | type: '', 182 | } 183 | if (val != null) { 184 | let svgs = []; 185 | if (val.svgs != null) 186 | svgs = val.svgs.split(','); 187 | a.g = g 188 | a.pn = val.pn; 189 | if (val.imgs != null) 190 | a.imgs = val.imgs.split(','); 191 | a.vendorPn = val.jlcpn; 192 | a.vendorUrl = val.jlcurl; 193 | a.vendor = 'jlc'; 194 | a.desc = val.desc; 195 | a.footprint = val.footprint; 196 | if (svgs.length > 0) { 197 | a.symbolUrl = svgs[0]; 198 | } 199 | if (svgs.length > 1) { 200 | a.fpUrl = svgs[1]; 201 | } 202 | if (val.datasheet != null) 203 | a.datasheet = val.datasheet; 204 | a.value = val.value; 205 | if (val.type_ != null) 206 | a.type = val.type_; 207 | if (val.prices != null) { 208 | const prices = val.prices.split(','); 209 | a.prices = [] 210 | for (const i in prices) { 211 | const m = prices[i].split(':'); 212 | a.prices.push({ 213 | num: m[0], 214 | price: m[1] 215 | }); 216 | } 217 | } 218 | } 219 | // // log.info(a) 220 | // log.info("return data") 221 | // evt.reply('data',a) 222 | return a; 223 | 224 | 225 | 226 | } 227 | connectBom(sync) { 228 | if (store.has('bomConParam')) { 229 | let bomConParam = store.get('bomConParam') 230 | bomConParam.logging = this.log 231 | bomConParam.synchronize = sync 232 | bomConParam.entities = [BomCap,BomRes,BomDiode,BomConnector] 233 | createConnection(bomConParam).then(() => { 234 | this.connected.bom = true; 235 | log.info("connect bom database ok"); 236 | 237 | this.repo.bom = { 238 | cap: getRepository(BomCap, 'bom'), 239 | res: getRepository(BomRes, 'bom'), 240 | diode: getRepository(BomDiode, 'bom'), 241 | connector: getRepository(BomConnector, 'bom'), 242 | } 243 | 244 | 245 | }).catch(err => { 246 | log.error(err) 247 | this.lastErr.bom = err; 248 | this.connected.bom = false 249 | }) 250 | } else { 251 | this.lastErr.bom = 'BOM connection parameter empty' 252 | this.connected.bom = false; 253 | } 254 | } 255 | connectJlc(sync) { 256 | let jlcConParam = { 257 | name: "jlc", 258 | type: "mysql", 259 | host: "www.whyengineer.com", 260 | port: 3306, 261 | username: "openbom-jlc", 262 | password: "openbom", 263 | database: "jlc", 264 | } 265 | jlcConParam.logging = this.log 266 | jlcConParam.synchronize = sync 267 | jlcConParam.entities = [Cap, Res, Diode, Connector] 268 | createConnection(jlcConParam).then(() => { 269 | this.connected.jlc = true; 270 | log.info("connect jlc database ok"); 271 | 272 | this.repo.jlc = { 273 | cap: getRepository(Cap, 'jlc'), 274 | res: getRepository(Res, 'jlc'), 275 | diode: getRepository(Diode, 'jlc'), 276 | connector: getRepository(Connector, 'jlc'), 277 | } 278 | 279 | 280 | }).catch(err => { 281 | log.error(err) 282 | this.lastErr.jlc = err 283 | this.connected.jlc = false; 284 | }) 285 | } 286 | connect(sync) { 287 | this.connectJlc(sync) 288 | this.connectBom(sync) 289 | } 290 | 291 | } -------------------------------------------------------------------------------- /src/db/entity/bom/Cap.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const BomCap = new EntitySchema({ 4 | name: "cap", 5 | columns: { 6 | id: { 7 | primary: true, 8 | type: "int", 9 | generated: "increment" 10 | }, 11 | pn: { 12 | type: String, 13 | nullable: false 14 | }, 15 | value: { 16 | type: String, 17 | nullable: false 18 | }, 19 | 20 | footprint: { 21 | type: String, 22 | nullable: false 23 | }, 24 | desc: { 25 | type: String, 26 | nullable: false 27 | }, 28 | type: { 29 | type: String, 30 | nullable: false 31 | }, 32 | datasheet: { 33 | type: String, 34 | nullable: true 35 | }, 36 | symbol: { 37 | type: String, 38 | nullable: true 39 | }, 40 | library_ref:{ 41 | type: String, 42 | nullable: true 43 | }, 44 | library_path:{ 45 | type: String, 46 | nullable: true 47 | }, 48 | footprint_path:{ 49 | type: String, 50 | nullable: true 51 | }, 52 | vendor1: { 53 | type: String, 54 | nullable: false 55 | }, 56 | vendor1_pn: { 57 | type: String, 58 | nullable: false 59 | }, 60 | vendor2: { 61 | type: String, 62 | nullable: true 63 | }, 64 | vendor2_pn: { 65 | type: String, 66 | nullable: true 67 | }, 68 | }, 69 | indices: [ 70 | { 71 | name: "value", 72 | unique: false, 73 | columns: [ 74 | "value", 75 | ] 76 | }, 77 | { 78 | name: "footprint", 79 | unique: false, 80 | columns: [ 81 | "footprint", 82 | ] 83 | }, 84 | { 85 | name: "pn", 86 | unique: true, 87 | columns: [ 88 | "pn", 89 | ] 90 | }, 91 | { 92 | name: "type", 93 | unique: false, 94 | columns: [ 95 | "type", 96 | ] 97 | }, 98 | ], 99 | }); -------------------------------------------------------------------------------- /src/db/entity/bom/Connector.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const BomConnector = new EntitySchema({ 4 | name: "connector", 5 | columns: { 6 | id: { 7 | primary: true, 8 | type: "int", 9 | generated: "increment" 10 | }, 11 | pn: { 12 | type: String, 13 | nullable: false 14 | }, 15 | value: { 16 | type: String, 17 | nullable: false 18 | }, 19 | 20 | footprint: { 21 | type: String, 22 | nullable: false 23 | }, 24 | desc: { 25 | type: String, 26 | nullable: false 27 | }, 28 | type: { 29 | type: String, 30 | nullable: false 31 | }, 32 | datasheet: { 33 | type: String, 34 | nullable: true 35 | }, 36 | symbol: { 37 | type: String, 38 | nullable: true 39 | }, 40 | library_ref:{ 41 | type: String, 42 | nullable: true 43 | }, 44 | library_path:{ 45 | type: String, 46 | nullable: true 47 | }, 48 | footprint_path:{ 49 | type: String, 50 | nullable: true 51 | }, 52 | vendor1: { 53 | type: String, 54 | nullable: false 55 | }, 56 | vendor1_pn: { 57 | type: String, 58 | nullable: false 59 | }, 60 | vendor2: { 61 | type: String, 62 | nullable: true 63 | }, 64 | vendor2_pn: { 65 | type: String, 66 | nullable: true 67 | }, 68 | }, 69 | indices: [ 70 | { 71 | name: "value", 72 | unique: false, 73 | columns: [ 74 | "value", 75 | ] 76 | }, 77 | { 78 | name: "footprint", 79 | unique: false, 80 | columns: [ 81 | "footprint", 82 | ] 83 | }, 84 | { 85 | name: "pn", 86 | unique: true, 87 | columns: [ 88 | "pn", 89 | ] 90 | }, 91 | { 92 | name: "type", 93 | unique: false, 94 | columns: [ 95 | "type", 96 | ] 97 | }, 98 | ], 99 | }); -------------------------------------------------------------------------------- /src/db/entity/bom/Diode.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const BomDiode = new EntitySchema({ 4 | name: "diode", 5 | columns: { 6 | id: { 7 | primary: true, 8 | type: "int", 9 | generated: "increment" 10 | }, 11 | pn: { 12 | type: String, 13 | nullable: false 14 | }, 15 | value: { 16 | type: String, 17 | nullable: false 18 | }, 19 | 20 | footprint: { 21 | type: String, 22 | nullable: false 23 | }, 24 | desc: { 25 | type: String, 26 | nullable: false 27 | }, 28 | type: { 29 | type: String, 30 | nullable: false 31 | }, 32 | datasheet: { 33 | type: String, 34 | nullable: true 35 | }, 36 | symbol: { 37 | type: String, 38 | nullable: true 39 | }, 40 | library_ref:{ 41 | type: String, 42 | nullable: true 43 | }, 44 | library_path:{ 45 | type: String, 46 | nullable: true 47 | }, 48 | footprint_path:{ 49 | type: String, 50 | nullable: true 51 | }, 52 | vendor1: { 53 | type: String, 54 | nullable: false 55 | }, 56 | vendor1_pn: { 57 | type: String, 58 | nullable: false 59 | }, 60 | vendor2: { 61 | type: String, 62 | nullable: true 63 | }, 64 | vendor2_pn: { 65 | type: String, 66 | nullable: true 67 | }, 68 | }, 69 | indices: [ 70 | { 71 | name: "value", 72 | unique: false, 73 | columns: [ 74 | "value", 75 | ] 76 | }, 77 | { 78 | name: "footprint", 79 | unique: false, 80 | columns: [ 81 | "footprint", 82 | ] 83 | }, 84 | { 85 | name: "pn", 86 | unique: true, 87 | columns: [ 88 | "pn", 89 | ] 90 | }, 91 | { 92 | name: "type", 93 | unique: false, 94 | columns: [ 95 | "type", 96 | ] 97 | }, 98 | ], 99 | }); -------------------------------------------------------------------------------- /src/db/entity/bom/Res.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const BomRes = new EntitySchema({ 4 | name: "res", 5 | columns: { 6 | id: { 7 | primary: true, 8 | type: "int", 9 | generated: "increment" 10 | }, 11 | pn: { 12 | type: String, 13 | nullable: false 14 | }, 15 | value: { 16 | type: String, 17 | nullable: false 18 | }, 19 | 20 | footprint: { 21 | type: String, 22 | nullable: false 23 | }, 24 | desc: { 25 | type: String, 26 | nullable: false 27 | }, 28 | type: { 29 | type: String, 30 | nullable: false 31 | }, 32 | datasheet: { 33 | type: String, 34 | nullable: true 35 | }, 36 | symbol: { 37 | type: String, 38 | nullable: true 39 | }, 40 | library_ref:{ 41 | type: String, 42 | nullable: true 43 | }, 44 | library_path:{ 45 | type: String, 46 | nullable: true 47 | }, 48 | footprint_path:{ 49 | type: String, 50 | nullable: true 51 | }, 52 | vendor1: { 53 | type: String, 54 | nullable: false 55 | }, 56 | vendor1_pn: { 57 | type: String, 58 | nullable: false 59 | }, 60 | vendor2: { 61 | type: String, 62 | nullable: true 63 | }, 64 | vendor2_pn: { 65 | type: String, 66 | nullable: true 67 | }, 68 | }, 69 | indices: [ 70 | { 71 | name: "value", 72 | unique: false, 73 | columns: [ 74 | "value", 75 | ] 76 | }, 77 | { 78 | name: "footprint", 79 | unique: false, 80 | columns: [ 81 | "footprint", 82 | ] 83 | }, 84 | { 85 | name: "pn", 86 | unique: true, 87 | columns: [ 88 | "pn", 89 | ] 90 | }, 91 | { 92 | name: "type", 93 | unique: false, 94 | columns: [ 95 | "type", 96 | ] 97 | }, 98 | ], 99 | }); -------------------------------------------------------------------------------- /src/db/entity/jlc/Cap.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const Cap = new EntitySchema({ 4 | name: "cap", 5 | columns: { 6 | pn: { 7 | primary: true, 8 | type: String, 9 | nullable: false 10 | }, 11 | value: { 12 | type: String, 13 | nullable: false 14 | }, 15 | footprint: { 16 | type: String, 17 | nullable: false 18 | }, 19 | jlcpn: { 20 | type: String, 21 | nullable: false 22 | }, 23 | jlcurl: { 24 | type: String, 25 | nullable: false 26 | }, 27 | prices: { 28 | type: String, 29 | nullable: true 30 | }, 31 | imgs: { 32 | type: String, 33 | nullable: true 34 | }, 35 | datasheet: { 36 | type: String, 37 | nullable: true 38 | }, 39 | desc: { 40 | type: String, 41 | nullable: false 42 | }, 43 | svgs: { 44 | type: String, 45 | nullable: true 46 | }, 47 | type_: { 48 | type: String, 49 | nullable: true 50 | }, 51 | }, 52 | indices: [ 53 | { 54 | name: "cap_value", 55 | unique: false, 56 | columns: [ 57 | "value", 58 | ] 59 | }, 60 | { 61 | name: "cap_footprint", 62 | unique: false, 63 | columns: [ 64 | "footprint", 65 | ] 66 | }, 67 | { 68 | name: "cap_jlcpn", 69 | unique: true, 70 | columns: [ 71 | "jlcpn", 72 | ] 73 | }, 74 | { 75 | name: "cap_jlcurl", 76 | unique: true, 77 | columns: [ 78 | "jlcurl", 79 | ] 80 | }, 81 | { 82 | name: "cap_type_", 83 | unique: false, 84 | columns: [ 85 | "type_", 86 | ] 87 | }, 88 | ], 89 | }); -------------------------------------------------------------------------------- /src/db/entity/jlc/Connector.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const Connector = new EntitySchema({ 4 | name: "connector", 5 | columns: { 6 | pn: { 7 | primary: true, 8 | type: String, 9 | nullable: false 10 | }, 11 | value: { 12 | type: String, 13 | nullable: false 14 | }, 15 | footprint: { 16 | type: String, 17 | nullable: false 18 | }, 19 | jlcpn: { 20 | type: String, 21 | nullable: false 22 | }, 23 | jlcurl: { 24 | type: String, 25 | nullable: false 26 | }, 27 | prices: { 28 | type: String, 29 | nullable: true 30 | }, 31 | imgs: { 32 | type: String, 33 | nullable: true 34 | }, 35 | datasheet: { 36 | type: String, 37 | nullable: true 38 | }, 39 | desc: { 40 | type: String, 41 | nullable: false 42 | }, 43 | svgs: { 44 | type: String, 45 | nullable: true 46 | }, 47 | type_: { 48 | type: String, 49 | nullable: true 50 | }, 51 | }, 52 | indices: [ 53 | { 54 | name: "connector_value", 55 | unique: false, 56 | columns: [ 57 | "value", 58 | ] 59 | }, 60 | { 61 | name: "connector_footprint", 62 | unique: false, 63 | columns: [ 64 | "footprint", 65 | ] 66 | }, 67 | { 68 | name: "connector_jlcpn", 69 | unique: true, 70 | columns: [ 71 | "jlcpn", 72 | ] 73 | }, 74 | { 75 | name: "connector_jlcurl", 76 | unique: true, 77 | columns: [ 78 | "jlcurl", 79 | ] 80 | }, 81 | { 82 | name: "connector_type_", 83 | unique: false, 84 | columns: [ 85 | "type_", 86 | ] 87 | }, 88 | ], 89 | }); -------------------------------------------------------------------------------- /src/db/entity/jlc/Diode.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const Diode = new EntitySchema({ 4 | name: "diode", 5 | columns: { 6 | pn: { 7 | primary: true, 8 | type: String, 9 | nullable: false 10 | }, 11 | value: { 12 | type: String, 13 | nullable: false 14 | }, 15 | footprint: { 16 | type: String, 17 | nullable: false 18 | }, 19 | jlcpn: { 20 | type: String, 21 | nullable: false 22 | }, 23 | jlcurl: { 24 | type: String, 25 | nullable: false 26 | }, 27 | prices: { 28 | type: String, 29 | nullable: true 30 | }, 31 | imgs: { 32 | type: String, 33 | nullable: true 34 | }, 35 | datasheet: { 36 | type: String, 37 | nullable: true 38 | }, 39 | desc: { 40 | type: String, 41 | nullable: false 42 | }, 43 | svgs: { 44 | type: String, 45 | nullable: true 46 | }, 47 | type_: { 48 | type: String, 49 | nullable: true 50 | }, 51 | }, 52 | indices: [ 53 | { 54 | name: "diode_value", 55 | unique: false, 56 | columns: [ 57 | "value", 58 | ] 59 | }, 60 | { 61 | name: "diode_footprint", 62 | unique: false, 63 | columns: [ 64 | "footprint", 65 | ] 66 | }, 67 | { 68 | name: "diode_jlcpn", 69 | unique: true, 70 | columns: [ 71 | "jlcpn", 72 | ] 73 | }, 74 | { 75 | name: "diode_jlcurl", 76 | unique: true, 77 | columns: [ 78 | "jlcurl", 79 | ] 80 | }, 81 | { 82 | name: "diode_type_", 83 | unique: false, 84 | columns: [ 85 | "type_", 86 | ] 87 | }, 88 | ], 89 | }); -------------------------------------------------------------------------------- /src/db/entity/jlc/Res.js: -------------------------------------------------------------------------------- 1 | import {EntitySchema} from "typeorm"; 2 | 3 | export const Res = new EntitySchema({ 4 | name: "res", 5 | columns: { 6 | pn: { 7 | primary: true, 8 | type: String, 9 | nullable: false 10 | }, 11 | value: { 12 | type: String, 13 | nullable: false 14 | }, 15 | footprint: { 16 | type: String, 17 | nullable: false 18 | }, 19 | jlcpn: { 20 | type: String, 21 | nullable: false 22 | }, 23 | jlcurl: { 24 | type: String, 25 | nullable: false 26 | }, 27 | prices: { 28 | type: String, 29 | nullable: true 30 | }, 31 | imgs: { 32 | type: String, 33 | nullable: true 34 | }, 35 | datasheet: { 36 | type: String, 37 | nullable: true 38 | }, 39 | desc: { 40 | type: String, 41 | nullable: false 42 | }, 43 | svgs: { 44 | type: String, 45 | nullable: true 46 | }, 47 | type_: { 48 | type: String, 49 | nullable: true 50 | }, 51 | }, 52 | indices: [ 53 | { 54 | name: "res_value", 55 | unique: false, 56 | columns: [ 57 | "value", 58 | ] 59 | }, 60 | { 61 | name: "res_footprint", 62 | unique: false, 63 | columns: [ 64 | "footprint", 65 | ] 66 | }, 67 | { 68 | name: "res_jlcpn", 69 | unique: true, 70 | columns: [ 71 | "jlcpn", 72 | ] 73 | }, 74 | { 75 | name: "res_jlcurl", 76 | unique: true, 77 | columns: [ 78 | "jlcurl", 79 | ] 80 | }, 81 | { 82 | name: "res_type_", 83 | unique: false, 84 | columns: [ 85 | "type_", 86 | ] 87 | }, 88 | ], 89 | }); -------------------------------------------------------------------------------- /src/db/search.js: -------------------------------------------------------------------------------- 1 | 2 | import FlexSearch from 'flexsearch' 3 | import log from 'electron-log' 4 | 5 | export default class Search { 6 | constructor(db, storeMemory=true) { 7 | this.db = db 8 | this.fs = {} 9 | this.map = {} 10 | this.memory = storeMemory 11 | } 12 | search(table, colume, type, msg,limit=20) { 13 | let key = table + colume + type 14 | let res2 = [] 15 | if(key in this.fs){ 16 | let res1 = this.fs[key].search(msg,limit) 17 | 18 | for (let i in res1) { 19 | if(this.memory){ 20 | res2.push(this.map[this.key].get(res1[i])) 21 | }else{ 22 | //TODO 23 | } 24 | } 25 | } 26 | return res2 27 | 28 | } 29 | buildSearch(table, colume, type, cb = null) { 30 | this.key = table + colume + type 31 | if (this.key in this.fs) { 32 | if (cb != null) 33 | cb(this.fs[this.key]) 34 | } else { 35 | this.table = table 36 | this.colume = colume 37 | this.type = type 38 | this.index = 0 39 | this.count = 0 40 | this.totalCount = 0 41 | this.cb = cb 42 | this.fs[this.key] = new FlexSearch() 43 | if(this.memory) 44 | this.map[this.key]= new Map() 45 | this.db[this.table][this.colume].count(`type_="${this.type}"`).then(val => { 46 | this.totalCount = val 47 | this.interFind() 48 | }).catch(err => { 49 | log.error(err) 50 | }) 51 | } 52 | } 53 | interFind() { 54 | this.db[this.table][this.colume].find({ 55 | skip: this.index * 500, 56 | take: 500, 57 | where: `type_="${this.type}"` 58 | }).then((val) => { 59 | 60 | this.count += val.length 61 | for (let i = 0; i < val.length; i++) { 62 | let item = val[i] 63 | if(this.memory) 64 | this.map[this.key].set(item.pn,item) 65 | 66 | this.fs[this.key].add(item.pn,item.value+';'+item.desc+';'+item.type+';'+item.jlcpn+';'+item.footprint) 67 | } 68 | this.index++ 69 | if (this.count >= this.totalCount) { 70 | /*done*/ 71 | // this.search(this.table, this.colume, this.type, '22pf') 72 | if (this.cb != null) 73 | this.cb(this.fs) 74 | } else { 75 | this.interFind() 76 | } 77 | 78 | }).catch(err => { 79 | log.error(err) 80 | }) 81 | } 82 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import './plugins/element.js' 6 | 7 | Vue.config.productionTip = false 8 | 9 | new Vue({ 10 | router, 11 | store, 12 | render: h => h(App) 13 | }).$mount('#app') 14 | -------------------------------------------------------------------------------- /src/plugins/element.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Element from 'element-ui' 3 | import 'element-ui/lib/theme-chalk/index.css' 4 | 5 | Vue.use(Element) 6 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Home from '../views/Home.vue' 4 | import Config from '../views/Config.vue' 5 | import Bom from '../views/Bom.vue' 6 | Vue.use(VueRouter) 7 | 8 | const routes = [ 9 | { 10 | path: '/', 11 | name: 'Home', 12 | component: Home 13 | }, 14 | { 15 | path: '/config', 16 | name: 'Config', 17 | component: Config 18 | }, 19 | { 20 | path: '/bom', 21 | name: 'Bom', 22 | component: Bom 23 | }, 24 | ] 25 | 26 | const router = new VueRouter({ 27 | mode: process.env.IS_ELECTRON ? 'hash' : 'history', 28 | base: process.env.BASE_URL, 29 | routes 30 | }) 31 | 32 | export default router 33 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | }, 9 | mutations: { 10 | }, 11 | actions: { 12 | }, 13 | modules: { 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /src/views/Bom.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /src/views/Config.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 60 | 61 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | configureWebpack: { 3 | // Webpack configuration applied to web builds and the electron renderer process 4 | }, 5 | pluginOptions: { 6 | electronBuilder: { 7 | nodeIntegration: true, 8 | chainWebpackMainProcess: () => { 9 | // Chain webpack config for electron main process only 10 | }, 11 | chainWebpackRendererProcess: () => { 12 | // Chain webpack config for electron renderer process only (won't be applied to web builds) 13 | }, 14 | mainProcessWatch: ['src/**/**.js'], 15 | // Provide a list of arguments that Electron will be launched with during "electron:serve", 16 | // which can be accessed from the main process (src/background.js). 17 | // Note that it is ignored when --debug flag is used with "electron:serve", as you must launch Electron yourself 18 | // Command line args (excluding --debug, --dashboard, and --headless) are passed to Electron as well 19 | mainProcessArgs: ['--arg-name', 'arg-value'], 20 | builderOptions: { 21 | "appId": "OpenBom", 22 | "copyright":"Copyright © 2020 WhyEngineer.com", 23 | "productName":"OpenBom", 24 | "win": { 25 | "icon": './public/openbom.ico', 26 | "target": [ 27 | { 28 | "target": "nsis" , 29 | 'arch': [ 30 | 'x64' 31 | ] 32 | } 33 | ], 34 | "publish": [ 35 | "github" 36 | ] 37 | }, 38 | 'nsis': { 39 | 'oneClick': false, 40 | 'allowElevation': true, 41 | 'perMachine': true, 42 | 'allowToChangeInstallationDirectory': true, 43 | 'installerIcon': './public/openbom.ico', 44 | 'uninstallerIcon': './public/openbom.ico', 45 | 'installerHeaderIcon': './public/openbom.ico', 46 | 'createDesktopShortcut': true, 47 | 'createStartMenuShortcut': true, 48 | 'license': 'LICENSE.txt', 49 | 'artifactName': 'OpenBom.exe', 50 | 'guid':'c00f7959-9630-4566-b0cb-9c6a154ec9b3', 51 | }, 52 | // options placed here will be merged with default configuration and passed to electron-builder 53 | }, 54 | }, 55 | 56 | } 57 | } --------------------------------------------------------------------------------