| @@ -1,3 +1,5 @@ | |||||
| /.idea/ | /.idea/ | ||||
| /src/main/resources/public/ | /src/main/resources/public/ | ||||
| /target/ | /target/ | ||||
| /rms.iml | |||||
| /app/node_modules/ | |||||
| @@ -0,0 +1,2 @@ | |||||
| # Default ignored files | |||||
| /workspace.xml | |||||
| @@ -1710,16 +1710,6 @@ | |||||
| "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", | ||||
| "dev": true | "dev": true | ||||
| }, | }, | ||||
| "ansi-styles": { | |||||
| "version": "4.3.0", | |||||
| "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", | |||||
| "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "color-convert": "^2.0.1" | |||||
| } | |||||
| }, | |||||
| "cacache": { | "cacache": { | ||||
| "version": "13.0.1", | "version": "13.0.1", | ||||
| "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", | "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", | ||||
| @@ -1752,34 +1742,6 @@ | |||||
| "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", | ||||
| "dev": true | "dev": true | ||||
| }, | }, | ||||
| "chalk": { | |||||
| "version": "4.1.0", | |||||
| "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", | |||||
| "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "ansi-styles": "^4.1.0", | |||||
| "supports-color": "^7.1.0" | |||||
| } | |||||
| }, | |||||
| "color-convert": { | |||||
| "version": "2.0.1", | |||||
| "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", | |||||
| "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "color-name": "~1.1.4" | |||||
| } | |||||
| }, | |||||
| "color-name": { | |||||
| "version": "1.1.4", | |||||
| "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", | |||||
| "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", | |||||
| "dev": true, | |||||
| "optional": true | |||||
| }, | |||||
| "css-loader": { | "css-loader": { | ||||
| "version": "3.6.0", | "version": "3.6.0", | ||||
| "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", | "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", | ||||
| @@ -1823,13 +1785,6 @@ | |||||
| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| "has-flag": { | |||||
| "version": "4.0.0", | |||||
| "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", | |||||
| "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", | |||||
| "dev": true, | |||||
| "optional": true | |||||
| }, | |||||
| "icss-utils": { | "icss-utils": { | ||||
| "version": "4.1.1", | "version": "4.1.1", | ||||
| "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", | "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", | ||||
| @@ -1839,18 +1794,6 @@ | |||||
| "postcss": "^7.0.14" | "postcss": "^7.0.14" | ||||
| } | } | ||||
| }, | }, | ||||
| "loader-utils": { | |||||
| "version": "2.0.0", | |||||
| "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", | |||||
| "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "big.js": "^5.2.2", | |||||
| "emojis-list": "^3.0.0", | |||||
| "json5": "^2.1.2" | |||||
| } | |||||
| }, | |||||
| "postcss-modules-extract-imports": { | "postcss-modules-extract-imports": { | ||||
| "version": "2.0.0", | "version": "2.0.0", | ||||
| "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", | "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", | ||||
| @@ -1914,16 +1857,6 @@ | |||||
| "minipass": "^3.1.1" | "minipass": "^3.1.1" | ||||
| } | } | ||||
| }, | }, | ||||
| "supports-color": { | |||||
| "version": "7.2.0", | |||||
| "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", | |||||
| "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "has-flag": "^4.0.0" | |||||
| } | |||||
| }, | |||||
| "terser-webpack-plugin": { | "terser-webpack-plugin": { | ||||
| "version": "2.3.8", | "version": "2.3.8", | ||||
| "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", | "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", | ||||
| @@ -1940,18 +1873,6 @@ | |||||
| "terser": "^4.6.12", | "terser": "^4.6.12", | ||||
| "webpack-sources": "^1.4.3" | "webpack-sources": "^1.4.3" | ||||
| } | } | ||||
| }, | |||||
| "vue-loader-v16": { | |||||
| "version": "npm:vue-loader@16.1.2", | |||||
| "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz", | |||||
| "integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "chalk": "^4.1.0", | |||||
| "hash-sum": "^2.0.0", | |||||
| "loader-utils": "^2.0.0" | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| @@ -11180,6 +11101,87 @@ | |||||
| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| "vue-loader-v16": { | |||||
| "version": "npm:vue-loader@16.1.2", | |||||
| "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.1.2.tgz", | |||||
| "integrity": "sha512-8QTxh+Fd+HB6fiL52iEVLKqE9N1JSlMXLR92Ijm6g8PZrwIxckgpqjPDWRP5TWxdiPaHR+alUWsnu1ShQOwt+Q==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "chalk": "^4.1.0", | |||||
| "hash-sum": "^2.0.0", | |||||
| "loader-utils": "^2.0.0" | |||||
| }, | |||||
| "dependencies": { | |||||
| "ansi-styles": { | |||||
| "version": "4.3.0", | |||||
| "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", | |||||
| "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "color-convert": "^2.0.1" | |||||
| } | |||||
| }, | |||||
| "chalk": { | |||||
| "version": "4.1.0", | |||||
| "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", | |||||
| "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "ansi-styles": "^4.1.0", | |||||
| "supports-color": "^7.1.0" | |||||
| } | |||||
| }, | |||||
| "color-convert": { | |||||
| "version": "2.0.1", | |||||
| "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", | |||||
| "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "color-name": "~1.1.4" | |||||
| } | |||||
| }, | |||||
| "color-name": { | |||||
| "version": "1.1.4", | |||||
| "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", | |||||
| "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", | |||||
| "dev": true, | |||||
| "optional": true | |||||
| }, | |||||
| "has-flag": { | |||||
| "version": "4.0.0", | |||||
| "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", | |||||
| "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", | |||||
| "dev": true, | |||||
| "optional": true | |||||
| }, | |||||
| "loader-utils": { | |||||
| "version": "2.0.0", | |||||
| "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", | |||||
| "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "big.js": "^5.2.2", | |||||
| "emojis-list": "^3.0.0", | |||||
| "json5": "^2.1.2" | |||||
| } | |||||
| }, | |||||
| "supports-color": { | |||||
| "version": "7.2.0", | |||||
| "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", | |||||
| "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", | |||||
| "dev": true, | |||||
| "optional": true, | |||||
| "requires": { | |||||
| "has-flag": "^4.0.0" | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| "vue-router": { | "vue-router": { | ||||
| "version": "3.5.1", | "version": "3.5.1", | ||||
| "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", | "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.1.tgz", | ||||
| @@ -3,7 +3,7 @@ | |||||
| "version": "0.1.0", | "version": "0.1.0", | ||||
| "private": true, | "private": true, | ||||
| "scripts": { | "scripts": { | ||||
| "serve": "vue-cli-service serve", | |||||
| "serve": "vue-cli-service serve --port 3000", | |||||
| "build": "vue-cli-service build", | "build": "vue-cli-service build", | ||||
| "lint": "vue-cli-service lint" | "lint": "vue-cli-service lint" | ||||
| }, | }, | ||||
| @@ -5,6 +5,8 @@ | |||||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||
| <meta name="viewport" content="width=device-width,initial-scale=1.0"> | <meta name="viewport" content="width=device-width,initial-scale=1.0"> | ||||
| <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> | ||||
| <link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet"> | |||||
| <title><%= htmlWebpackPlugin.options.title %></title> | <title><%= htmlWebpackPlugin.options.title %></title> | ||||
| </head> | </head> | ||||
| <body> | <body> | ||||
| @@ -1,10 +1,44 @@ | |||||
| <template> | <template> | ||||
| <v-app> | |||||
| <router-view /> | |||||
| </v-app> | |||||
| <v-app> | |||||
| <router-view @authenticated="setAuthenticated"/> | |||||
| </v-app> | |||||
| </template> | </template> | ||||
| <script> | <script> | ||||
| export default { | |||||
| name: 'App', | |||||
| } | |||||
| export default { | |||||
| name: 'App', | |||||
| computed: { | |||||
| authenticated() { | |||||
| return localStorage.getItem('username') != null; | |||||
| } | |||||
| }, | |||||
| mounted() { | |||||
| if (!this.authenticated) { | |||||
| this.$router.replace({name: "login"}); | |||||
| } else { | |||||
| this.$router.replace({name: "asset_group"}); | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| setAuthenticated(user) { | |||||
| if (user) { | |||||
| localStorage.setItem('username', user.username); | |||||
| localStorage.setItem('roles', user.roles); | |||||
| } else { | |||||
| this.logout(); | |||||
| } | |||||
| this.$router.replace({ name: 'asset_group' }); | |||||
| }, | |||||
| logout() { | |||||
| this.$axios.get('/logout').then((resp) => { | |||||
| console.log(resp); | |||||
| }) | |||||
| .catch(function (resp) { | |||||
| console.log(resp); | |||||
| }); | |||||
| localStorage.removeItem('username'); | |||||
| localStorage.removeItem('roles'); | |||||
| this.$router.replace({name: "login"}); | |||||
| } | |||||
| } | |||||
| } | |||||
| </script> | </script> | ||||
| @@ -0,0 +1,201 @@ | |||||
| <template> | |||||
| <div class="dashboard"> | |||||
| <h1>歷史報表檢視</h1> | |||||
| <v-card> | |||||
| <v-card-title> | |||||
| 歷史報表 -- 共 {{reports.length}} 筆 | |||||
| <v-spacer></v-spacer> | |||||
| <v-select | |||||
| v-model="select" | |||||
| :items="reportconfs" | |||||
| :rules="[v => !!v || '必須要選擇一個報表']" | |||||
| label="選擇報表" | |||||
| required | |||||
| item-text="nameId" | |||||
| item-value="id" | |||||
| @change="loadReport()" | |||||
| ></v-select> | |||||
| <div class="px-1"></div> | |||||
| <v-menu | |||||
| v-model="menu2" | |||||
| :close-on-content-click="false" | |||||
| :nudge-right="40" | |||||
| transition="scale-transition" | |||||
| offset-y | |||||
| min-width="100px" | |||||
| class="mr-3" | |||||
| > | |||||
| <template v-slot:activator="{ on }"> | |||||
| <v-text-field | |||||
| v-model="date" | |||||
| label="選擇報表日期" | |||||
| prepend-icon="mdi-calendar" | |||||
| readonly | |||||
| v-on="on" | |||||
| @change="loadReport()" | |||||
| ></v-text-field> | |||||
| </template> | |||||
| <v-date-picker v-model="date" @input="menu2 = false;loadReport()"></v-date-picker> | |||||
| </v-menu> | |||||
| <div v-if="isAdmin" class="pl-4 mb-3"> | |||||
| <v-tooltip bottom> | |||||
| <template v-slot:activator="{ on, attrs }"> | |||||
| <v-btn | |||||
| color="primary" | |||||
| dark | |||||
| v-bind="attrs" | |||||
| v-on="on" | |||||
| @click="generateReport()" | |||||
| > | |||||
| 重新產生報表 | |||||
| </v-btn> | |||||
| </template> | |||||
| <span>以選定日期重新產生報表, 不會發送 Email 及 FTP</span> | |||||
| </v-tooltip> | |||||
| </div> | |||||
| </v-card-title> | |||||
| <v-data-table | |||||
| :headers="headers" | |||||
| :items="reports" | |||||
| :search="search" | |||||
| > | |||||
| <template v-slot:item.fileName="{ item }"> | |||||
| <a href="javascript:void(0)" @click="download(item.filePath)">{{item.fileName}}</a> | |||||
| </template> | |||||
| </v-data-table> | |||||
| </v-card> | |||||
| <v-snackbar | |||||
| v-model="snackbar" | |||||
| :color="snackbarColor" | |||||
| :timeout="snackbarTimeout" | |||||
| absolute | |||||
| right | |||||
| rounded="pill" | |||||
| top | |||||
| > | |||||
| {{snackbarMessage}}. | |||||
| </v-snackbar> | |||||
| </div> | |||||
| </template> | |||||
| <script> | |||||
| import axios from 'axios'; | |||||
| export default { | |||||
| name: 'AssetGroup', | |||||
| data () { | |||||
| return { | |||||
| search: '', | |||||
| select: null, | |||||
| reportconfs: [], | |||||
| date: new Date().toISOString().substr(0, 10), | |||||
| menu2: false, | |||||
| headers: [ | |||||
| { text: '檔案名稱', value: 'fileName',}, | |||||
| { text: '產生時間', value: 'fileDate' }, | |||||
| // { text: '產生狀態', value: 'genstate' }, | |||||
| // { text: 'FTP 狀態', value: 'ftpstate' }, | |||||
| // { text: 'Email 狀態', value: 'emailstate' }, | |||||
| ], | |||||
| reports: [], | |||||
| snackbar: false, | |||||
| snackbarMessage: "", | |||||
| snackbarColor: "blue-grey", | |||||
| snackbarTimeout: 1000, | |||||
| } | |||||
| }, | |||||
| created() { | |||||
| this.initialize(); | |||||
| }, | |||||
| computed: { | |||||
| isAdmin() { | |||||
| let roles = localStorage.getItem( 'roles'); | |||||
| let admin = (roles != null && roles.indexOf('ADMIN') >= 0 ); | |||||
| console.log("isAdmin", admin); | |||||
| return admin; | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| initialize() { | |||||
| // axios.get("/api/access/reportview/listconf", this.editedItem) | |||||
| // .then((result) => { | |||||
| // let json = result.data; | |||||
| // this.reportconfs = json.data | |||||
| // if (this.reportconfs && this.reportconfs.length > 0) { | |||||
| // this.select = this.reportconfs[0].id; | |||||
| // this.loadReport(); | |||||
| // } | |||||
| // }); | |||||
| }, | |||||
| loadReport() { | |||||
| axios.get("/api/access/reportview/listreport/"+ this.select + "/" + this.date) | |||||
| .then((result) => { | |||||
| let json = result.data; | |||||
| if (json.status === "OK") | |||||
| this.reports = json.data; | |||||
| else { | |||||
| this.reports = []; | |||||
| this.$root.$emit('showError', json.message); | |||||
| } | |||||
| }); | |||||
| }, | |||||
| download(file) { | |||||
| axios({ | |||||
| url: '/api/access/reportview/download?file=' + file, //your url | |||||
| method: 'GET', | |||||
| responseType: 'blob', // important | |||||
| }).then((response) => { | |||||
| const url = window.URL.createObjectURL(new Blob([response.data])); | |||||
| const link = document.createElement('a'); | |||||
| console.log(response); | |||||
| console.log(file); | |||||
| file = file.replace("\\", "/"); | |||||
| const fileName = file.substr(file.lastIndexOf("/")+1); | |||||
| link.href = url; | |||||
| link.setAttribute('download', fileName); //or any other extension | |||||
| document.body.appendChild(link); | |||||
| link.click(); | |||||
| }); | |||||
| }, | |||||
| generateReport() { | |||||
| let reportId = this.select; | |||||
| let date = this.date; | |||||
| axios({ | |||||
| url: '/api/access/reportview/genreport/' + reportId + "/" + date, //your url | |||||
| method: 'GET', | |||||
| }).then((response) => { | |||||
| let json = response.data; | |||||
| if (json.status === "OK") { | |||||
| this.snackbarMessage = "報表在背景執行,請稍候…"; | |||||
| this.snackbarColor = "blue-grey"; | |||||
| this.snackbarTimeout = 1000, | |||||
| this.snackbar = true; | |||||
| setTimeout(this.checkReportStatus, 1000); | |||||
| } | |||||
| else { | |||||
| this.snackbarMessage = "報表無法執行:" + json.message; | |||||
| this.snackbarColor = "deep-orange"; | |||||
| this.snackbar = true; | |||||
| } | |||||
| }); | |||||
| }, | |||||
| checkReportStatus() { | |||||
| axios({ | |||||
| url: '/api/access/reportview/genreport/status', //your url | |||||
| method: 'GET', | |||||
| }).then((response) => { | |||||
| let json = response.data; | |||||
| if (json.status === "OK" && json.data === true) { | |||||
| this.snackbarMessage = "報表仍在背景執行,請稍候…"; | |||||
| this.snackbar = true; | |||||
| setTimeout(this.checkReportStatus, 1000); | |||||
| } | |||||
| else{ | |||||
| this.snackbarMessage = "報表執行完畢!"; | |||||
| this.snackbarTimeout = 3000, | |||||
| this.snackbar = true; | |||||
| this.loadReport(); | |||||
| } | |||||
| }); | |||||
| }, | |||||
| }, | |||||
| } | |||||
| </script> | |||||
| @@ -0,0 +1,8 @@ | |||||
| <template> | |||||
| <div></div> | |||||
| </template> | |||||
| <script> | |||||
| export default { | |||||
| name: '' | |||||
| } | |||||
| </script> | |||||
| @@ -0,0 +1,153 @@ | |||||
| <template> | |||||
| <div> | |||||
| <v-data-table class="pa-3 pt-5" :headers="headers"> | |||||
| <template v-slot:top> | |||||
| <v-toolbar flat> | |||||
| <v-dialog | |||||
| v-model="dialog" | |||||
| max-width="500px" | |||||
| > | |||||
| <template v-slot:activator="{ on, attrs }"> | |||||
| <v-spacer></v-spacer> | |||||
| <v-btn | |||||
| color="primary" | |||||
| v-bind="attrs" | |||||
| v-on="on" | |||||
| > | |||||
| <v-icon large>mdi-plus-circle</v-icon> | |||||
| 新增 | |||||
| </v-btn> | |||||
| </template> | |||||
| <v-card> | |||||
| <v-card-title> | |||||
| <!-- <span class="headline">{{ formTitle }}</span>--> | |||||
| </v-card-title> | |||||
| <!-- <v-card-text>--> | |||||
| <!-- <v-container>--> | |||||
| <!-- <v-row>--> | |||||
| <!-- <v-col--> | |||||
| <!-- cols="12"--> | |||||
| <!-- sm="6"--> | |||||
| <!-- md="4"--> | |||||
| <!-- >--> | |||||
| <!-- <v-text-field--> | |||||
| <!-- v-model="editedItem.name"--> | |||||
| <!-- label="Dessert name"--> | |||||
| <!-- ></v-text-field>--> | |||||
| <!-- </v-col>--> | |||||
| <!-- <v-col--> | |||||
| <!-- cols="12"--> | |||||
| <!-- sm="6"--> | |||||
| <!-- md="4"--> | |||||
| <!-- >--> | |||||
| <!-- <v-text-field--> | |||||
| <!-- v-model="editedItem.calories"--> | |||||
| <!-- label="Calories"--> | |||||
| <!-- ></v-text-field>--> | |||||
| <!-- </v-col>--> | |||||
| <!-- <v-col--> | |||||
| <!-- cols="12"--> | |||||
| <!-- sm="6"--> | |||||
| <!-- md="4"--> | |||||
| <!-- >--> | |||||
| <!-- <v-text-field--> | |||||
| <!-- v-model="editedItem.fat"--> | |||||
| <!-- label="Fat (g)"--> | |||||
| <!-- ></v-text-field>--> | |||||
| <!-- </v-col>--> | |||||
| <!-- <v-col--> | |||||
| <!-- cols="12"--> | |||||
| <!-- sm="6"--> | |||||
| <!-- md="4"--> | |||||
| <!-- >--> | |||||
| <!-- <v-text-field--> | |||||
| <!-- v-model="editedItem.carbs"--> | |||||
| <!-- label="Carbs (g)"--> | |||||
| <!-- ></v-text-field>--> | |||||
| <!-- </v-col>--> | |||||
| <!-- <v-col--> | |||||
| <!-- cols="12"--> | |||||
| <!-- sm="6"--> | |||||
| <!-- md="4"--> | |||||
| <!-- >--> | |||||
| <!-- <v-text-field--> | |||||
| <!-- v-model="editedItem.protein"--> | |||||
| <!-- label="Protein (g)"--> | |||||
| <!-- ></v-text-field>--> | |||||
| <!-- </v-col>--> | |||||
| <!-- </v-row>--> | |||||
| <!-- </v-container>--> | |||||
| <!-- </v-card-text>--> | |||||
| <v-card-actions> | |||||
| <v-spacer></v-spacer> | |||||
| <!-- <v-btn--> | |||||
| <!-- color="blue darken-1"--> | |||||
| <!-- text--> | |||||
| <!-- @click="close"--> | |||||
| <!-- >--> | |||||
| <!-- Cancel--> | |||||
| <!-- </v-btn>--> | |||||
| <!-- <v-btn--> | |||||
| <!-- color="blue darken-1"--> | |||||
| <!-- text--> | |||||
| <!-- @click="save"--> | |||||
| <!-- >--> | |||||
| <!-- Save--> | |||||
| <!-- </v-btn>--> | |||||
| </v-card-actions> | |||||
| </v-card> | |||||
| </v-dialog> | |||||
| <!-- <v-dialog v-model="dialogDelete" max-width="500px">--> | |||||
| <!-- <v-card>--> | |||||
| <!-- <v-card-title class="headline">Are you sure you want to delete this item?</v-card-title>--> | |||||
| <!-- <v-card-actions>--> | |||||
| <!-- <v-spacer></v-spacer>--> | |||||
| <!-- <v-btn color="blue darken-1" text @click="closeDelete">Cancel</v-btn>--> | |||||
| <!-- <v-btn color="blue darken-1" text @click="deleteItemConfirm">OK</v-btn>--> | |||||
| <!-- <v-spacer></v-spacer>--> | |||||
| <!-- </v-card-actions>--> | |||||
| <!-- </v-card>--> | |||||
| <!-- </v-dialog>--> | |||||
| </v-toolbar> | |||||
| </template> | |||||
| </v-data-table> | |||||
| </div> | |||||
| </template> | |||||
| <script> | |||||
| export default { | |||||
| name: '', | |||||
| data() { | |||||
| return { | |||||
| dialog: false, | |||||
| headers: [ | |||||
| {text: '主機名稱', value: 'hostname'}, | |||||
| {text: '資產群組', value: 'type'}, | |||||
| {text: '對應應用系統', value: 'descript'}, | |||||
| {text: 'IP1', value: 'ip1'}, | |||||
| {text: 'IP2', value: 'ip2'}, | |||||
| {text: '機型(型號)', value: 'model'}, | |||||
| {text: '環境別', value: 'environment'}, | |||||
| {text: '放置地點', value: 'position'}, | |||||
| {text: '機櫃編號', value: 'position_number'}, | |||||
| {text: '數量', value: 'amount'}, | |||||
| {text: '擁有者', value: 'owner_department'}, | |||||
| {text: '保管單位', value: 'keep_department'}, | |||||
| {text: '保管者', value: 'keeper'}, | |||||
| {text: '備註', value: 'remark'}, | |||||
| ], | |||||
| items: [], | |||||
| } | |||||
| }, | |||||
| mounted() { | |||||
| this.getHardwares(); | |||||
| }, | |||||
| methods: { | |||||
| async getHardwares() { | |||||
| this.items = await this.$axios.get('/hardware/hardwares'); | |||||
| } | |||||
| } | |||||
| } | |||||
| </script> | |||||
| @@ -0,0 +1,154 @@ | |||||
| <template> | |||||
| <v-app id="inspire"> | |||||
| <v-navigation-drawer | |||||
| v-model="drawer" | |||||
| :clipped="$vuetify.breakpoint.lgAndUp" | |||||
| app | |||||
| > | |||||
| <v-list dense> | |||||
| <template v-for="item in items"> | |||||
| <v-list-group | |||||
| v-if="item.children" | |||||
| :key="item.text" | |||||
| v-model="item.model" | |||||
| :prepend-icon="item.model ? item.icon : item['icon-alt']" | |||||
| append-icon="" | |||||
| > | |||||
| <template v-slot:activator> | |||||
| <v-list-item-content> | |||||
| <v-list-item-title> | |||||
| {{ item.text }} | |||||
| </v-list-item-title> | |||||
| </v-list-item-content> | |||||
| </template> | |||||
| <v-list-item | |||||
| v-for="(child, i) in item.children" | |||||
| :key="i" | |||||
| link | |||||
| :to="child.route" | |||||
| > | |||||
| <v-list-item-action v-if="child.icon"> | |||||
| <v-icon>{{ child.icon }}</v-icon> | |||||
| </v-list-item-action> | |||||
| <v-list-item-content> | |||||
| <v-list-item-title> | |||||
| {{ child.text }} | |||||
| </v-list-item-title> | |||||
| </v-list-item-content> | |||||
| </v-list-item> | |||||
| </v-list-group> | |||||
| <v-list-item | |||||
| v-else | |||||
| :key="item.text" | |||||
| link | |||||
| :to="item.route" | |||||
| > | |||||
| <v-list-item-action> | |||||
| <v-icon>{{ item.icon }}</v-icon> | |||||
| </v-list-item-action> | |||||
| <v-list-item-content> | |||||
| <v-list-item-title> | |||||
| {{ item.text }} | |||||
| </v-list-item-title> | |||||
| </v-list-item-content> | |||||
| </v-list-item> | |||||
| </template> | |||||
| </v-list> | |||||
| </v-navigation-drawer> | |||||
| <v-app-bar | |||||
| :clipped-left="$vuetify.breakpoint.lgAndUp" | |||||
| app | |||||
| color="blue darken-3" | |||||
| dark | |||||
| > | |||||
| <v-app-bar-nav-icon @click.stop="drawer = !drawer" /> | |||||
| <v-toolbar-title | |||||
| style="width: 400px" | |||||
| class="ml-0 pl-4" | |||||
| > | |||||
| <span class="hidden-sm-and-down">資訊資產管理系統</span> | |||||
| </v-toolbar-title> | |||||
| <v-spacer /> | |||||
| <v-btn | |||||
| icon | |||||
| large | |||||
| @click="logout" | |||||
| > | |||||
| <v-avatar | |||||
| size="32px" | |||||
| item | |||||
| > | |||||
| <v-img | |||||
| src="logo.svg" | |||||
| alt="Vuetify" | |||||
| /></v-avatar> | |||||
| </v-btn> | |||||
| </v-app-bar> | |||||
| <v-content> | |||||
| <v-container class="grey lighten-5"> | |||||
| <keep-alive> | |||||
| <router-view></router-view> | |||||
| </keep-alive> | |||||
| </v-container> | |||||
| </v-content> | |||||
| <v-snackbar v-model="error" top :timeout="2500"> | |||||
| {{ message }} | |||||
| <v-btn | |||||
| color="pink" | |||||
| text | |||||
| @click="error = false" | |||||
| > | |||||
| Close | |||||
| </v-btn> | |||||
| </v-snackbar> | |||||
| </v-app> | |||||
| </template> | |||||
| <script> | |||||
| export default { | |||||
| components: { | |||||
| }, | |||||
| props: { | |||||
| source: String, | |||||
| }, | |||||
| data: () => ({ | |||||
| dialog: false, | |||||
| drawer: null, | |||||
| error: false, | |||||
| message: "", | |||||
| }), | |||||
| created(){ | |||||
| this.$root.$on('showError', (message) => { | |||||
| this.error = true; | |||||
| this.message = message; | |||||
| }); | |||||
| }, | |||||
| computed: { | |||||
| isAdmin() { | |||||
| let roles = localStorage.getItem('roles'); | |||||
| return (roles != null && roles.indexOf('ADMIN') >= 0 ); | |||||
| }, | |||||
| items() { | |||||
| let ret = [ | |||||
| { icon: 'mdi-history', text: '資訊資產群組', route: '/asset_group' }, | |||||
| { icon: 'mdi-history', text: '硬體', route: '/hardware' }, | |||||
| { icon: 'mdi-history', text: '軟體', route: '/software' }, | |||||
| { icon: 'mdi-history', text: '資料與文件', route: '/fileAndData' }, | |||||
| { icon: 'mdi-history', text: '人員', route: '/person' }, | |||||
| ]; | |||||
| // if (this.isAdmin) { | |||||
| // ret.push({ icon: 'mdi-account', text: '帳號權限管理', route: '/account' }); | |||||
| // ret.push({ icon: 'mdi-poll-box', text: '報表組態管理', route: '/report_conf' }); | |||||
| // ret.push({ icon: 'mdi-message', text: '通知信管理', route: '/notice' }); | |||||
| // ret.push({ icon: 'mdi-account-details', text: '收信人管理', route: '/receiver' }); | |||||
| // } | |||||
| return ret; | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| logout(){ | |||||
| this.$emit("authenticated", null); | |||||
| }, | |||||
| } | |||||
| } | |||||
| </script> | |||||
| @@ -1,10 +1,128 @@ | |||||
| <template> | <template> | ||||
| <v-container> | |||||
| <div class="d-flex justify-center font-weight-bold title">Login</div> | |||||
| </v-container> | |||||
| <v-main> | |||||
| <v-container | |||||
| class='fill-height' | |||||
| fluid | |||||
| > | |||||
| <v-row | |||||
| align='center' | |||||
| justify='center' | |||||
| > | |||||
| <v-col | |||||
| cols='12' | |||||
| sm='8' | |||||
| md='4' | |||||
| > | |||||
| <v-card class='elevation-12'> | |||||
| <v-toolbar | |||||
| color='primary' | |||||
| dark | |||||
| flat | |||||
| > | |||||
| <v-toolbar-title>資訊資產管理系統</v-toolbar-title> | |||||
| <v-spacer /> | |||||
| </v-toolbar> | |||||
| <v-card-text> | |||||
| <v-form> | |||||
| <v-text-field | |||||
| v-model='input.username' | |||||
| label='Login' | |||||
| name='login' | |||||
| prepend-icon='mdi-account' | |||||
| type='text' | |||||
| /> | |||||
| <v-text-field | |||||
| v-model='input.password' | |||||
| id='password' | |||||
| label='Password' | |||||
| name='password' | |||||
| prepend-icon='mdi-lock' | |||||
| type='password' | |||||
| /> | |||||
| </v-form> | |||||
| </v-card-text> | |||||
| <v-card-actions> | |||||
| <v-spacer /> | |||||
| <v-btn color='primary' v-on:click='logintest()'>Login</v-btn> | |||||
| </v-card-actions> | |||||
| </v-card> | |||||
| </v-col> | |||||
| </v-row> | |||||
| </v-container> | |||||
| <v-snackbar v-model='loginError' top :timeout='2500'> | |||||
| {{ message }} | |||||
| <v-btn | |||||
| color='pink' | |||||
| text | |||||
| @click='loginError = false' | |||||
| > | |||||
| Close | |||||
| </v-btn> | |||||
| </v-snackbar> | |||||
| </v-main> | |||||
| </template> | </template> | ||||
| <script> | <script> | ||||
| export default { | export default { | ||||
| name: 'Login' | |||||
| name: 'Login', | |||||
| data() { | |||||
| return { | |||||
| input: { | |||||
| username: '', | |||||
| password: '', | |||||
| }, | |||||
| loginError : false, | |||||
| message : '', | |||||
| } | |||||
| }, | |||||
| methods: { | |||||
| logintest() { | |||||
| console.log('asd'); | |||||
| this.$emit('authenticated', | |||||
| { | |||||
| 'username':'aaa', | |||||
| 'roles': 'aaa', | |||||
| }); | |||||
| }, | |||||
| login() { | |||||
| this.loginError = false; | |||||
| const _this = this; | |||||
| if(this.input.username !== '' && this.input.password !== '') { | |||||
| const bodyFormData = new FormData(); | |||||
| bodyFormData.set('username', this.input.username); | |||||
| bodyFormData.set('password', this.input.password); | |||||
| this.$axios.post('/login', this.input).then((resp) => { | |||||
| if (resp.status === 200) { | |||||
| //成功 | |||||
| const json = resp.data; | |||||
| if (json.status === 'OK') { | |||||
| _this.$emit('authenticated', | |||||
| { | |||||
| 'username': _this.input.username, | |||||
| 'roles': json.data | |||||
| }); | |||||
| _this.$router.replace({ name: 'report_view' }); | |||||
| } else { | |||||
| _this.message = json.message; | |||||
| _this.loginError = true; | |||||
| } | |||||
| } else { | |||||
| _this.message = 'The username and / or password is incorrect'; | |||||
| _this.loginError = true; | |||||
| } | |||||
| console.log(resp); | |||||
| }) | |||||
| .catch(function (response) { | |||||
| //handle error | |||||
| console.log(response); | |||||
| }); | |||||
| } else { | |||||
| this.message = '請輸入帳號及密碼'; | |||||
| this.loginError = true; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| </script> | </script> | ||||
| @@ -0,0 +1,8 @@ | |||||
| <template> | |||||
| <div></div> | |||||
| </template> | |||||
| <script> | |||||
| export default { | |||||
| name: '' | |||||
| } | |||||
| </script> | |||||
| @@ -0,0 +1,8 @@ | |||||
| <template> | |||||
| <div></div> | |||||
| </template> | |||||
| <script> | |||||
| export default { | |||||
| name: '' | |||||
| } | |||||
| </script> | |||||
| @@ -6,12 +6,12 @@ import router from './router/index' | |||||
| import axios from './plugins/axios' | import axios from './plugins/axios' | ||||
| import vuetify from '@/plugins/vuetify' | import vuetify from '@/plugins/vuetify' | ||||
| Vue.config.productionTip = false | |||||
| Vue.config.productionTip = false; | |||||
| Vue.prototype.$axios = axios; | |||||
| new Vue({ | new Vue({ | ||||
| router, | router, | ||||
| axios, | |||||
| vuetify, | vuetify, | ||||
| render: h => h(App), | render: h => h(App), | ||||
| }).$mount('#app') | |||||
| }).$mount('#app'); | |||||
| @@ -2,11 +2,11 @@ import axios from 'axios'; | |||||
| //在開發環境中的測試 development | //在開發環境中的測試 development | ||||
| if(process.env.NODE_ENV === 'development') { | if(process.env.NODE_ENV === 'development') { | ||||
| axios.defaults.baseURL = '/' | |||||
| axios.defaults.baseURL = '/api' | |||||
| } | } | ||||
| //在生產環境中的測試 production | //在生產環境中的測試 production | ||||
| if(process.env.NODE_ENV === 'production') { | if(process.env.NODE_ENV === 'production') { | ||||
| axios.defaults.baseURL = '/' | |||||
| axios.defaults.baseURL = '/api' | |||||
| } | } | ||||
| axios.defaults.headers.post['Content-Type'] = 'charset=utf-8'; | axios.defaults.headers.post['Content-Type'] = 'charset=utf-8'; | ||||
| axios.defaults.headers.common.Pragma = 'no-cache'; | axios.defaults.headers.common.Pragma = 'no-cache'; | ||||
| @@ -1,29 +1,53 @@ | |||||
| import Vue from 'vue' | import Vue from 'vue' | ||||
| import Router from 'vue-router' | import Router from 'vue-router' | ||||
| import Login from '@/components/Login' | import Login from '@/components/Login' | ||||
| import Home from "../components/Home"; | |||||
| import AssetGroup from "../components/AssetGroup"; | |||||
| import Hardware from "../components/Hardware"; | |||||
| import Software from "../components/Software"; | |||||
| import FileAndData from "../components/FileAndData"; | |||||
| import Person from "../components/Person"; | |||||
| Vue.use(Router) | |||||
| Vue.use(Router); | |||||
| export const constantRoutes = [ | export const constantRoutes = [ | ||||
| { | { | ||||
| path: '/', | |||||
| alias: '/login', | |||||
| path: '/login', | |||||
| name: 'login', | |||||
| component: Login, | component: Login, | ||||
| }, | }, | ||||
| // { | |||||
| // path: '/', | |||||
| // component: , | |||||
| // name: '', | |||||
| // children: [ | |||||
| // { | |||||
| // path: '', | |||||
| // component: () => import(''), | |||||
| // name: '', | |||||
| // meta: { | |||||
| // }, | |||||
| // }, | |||||
| // ], | |||||
| // }, | |||||
| { | |||||
| path: '/home', | |||||
| component: Home, | |||||
| name: 'home', | |||||
| children: [ | |||||
| { | |||||
| path: '/asset_group', | |||||
| name: 'asset_group', | |||||
| component: AssetGroup | |||||
| }, | |||||
| { | |||||
| path: '/hardware', | |||||
| name: 'hardware', | |||||
| component: Hardware | |||||
| }, | |||||
| { | |||||
| path: '/software', | |||||
| name: 'software', | |||||
| component: Software | |||||
| }, | |||||
| { | |||||
| path: '/fileAndData', | |||||
| name: 'fileAndData', | |||||
| component: FileAndData | |||||
| }, | |||||
| { | |||||
| path: '/person', | |||||
| name: 'person', | |||||
| component: Person | |||||
| }, | |||||
| ] | |||||
| } | |||||
| ]; | ]; | ||||
| export default new Router({ | export default new Router({ | ||||
| @@ -57,6 +57,10 @@ | |||||
| <scope>test</scope> | <scope>test</scope> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-jdbc</artifactId> | |||||
| </dependency> | |||||
| <dependency> | <dependency> | ||||
| <groupId>org.jdbi</groupId> | <groupId>org.jdbi</groupId> | ||||
| @@ -92,6 +96,17 @@ | |||||
| <version>1.18.16</version> | <version>1.18.16</version> | ||||
| <optional>true</optional> | <optional>true</optional> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.slf4j</groupId> | |||||
| <artifactId>slf4j-api</artifactId> | |||||
| <version>1.7.30</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.slf4j</groupId> | |||||
| <artifactId>slf4j-simple</artifactId> | |||||
| <version>1.7.30</version> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -3,9 +3,10 @@ package com.moze.rms; | |||||
| import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; | |||||
| @SpringBootApplication | @SpringBootApplication | ||||
| public class RmsApplication { | |||||
| public class RmsApplication extends SpringBootServletInitializer { | |||||
| public static void main(String[] args) { | public static void main(String[] args) { | ||||
| SpringApplication.run(RmsApplication.class, args); | SpringApplication.run(RmsApplication.class, args); | ||||
| @@ -0,0 +1,55 @@ | |||||
| package com.moze.rms.config; | |||||
| import com.moze.rms.dao.HardwareDAO; | |||||
| import org.jdbi.v3.core.Jdbi; | |||||
| import org.jdbi.v3.core.statement.SqlLogger; | |||||
| import org.jdbi.v3.core.statement.StatementContext; | |||||
| import org.jdbi.v3.sqlobject.SqlObjectPlugin; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; | |||||
| import javax.sql.DataSource; | |||||
| @Configuration | |||||
| public class JdbiFactory { | |||||
| @Autowired | |||||
| DataSource dataSource; | |||||
| @Bean | |||||
| public Jdbi getInstance() { | |||||
| TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(dataSource); | |||||
| Jdbi jdbi = Jdbi.create(proxy); | |||||
| jdbi.setSqlLogger(new SqlLogger() { | |||||
| @Override | |||||
| public void logBeforeExecution(StatementContext ctx) { | |||||
| if (ctx.getStatement() != null) | |||||
| System.out.println(ctx.getStatement().toString()); | |||||
| } | |||||
| // @Override | |||||
| // public void logAfterExecution(StatementContext context) { | |||||
| //// jdbi.setSqlLogger(SqlLogger.NOP_SQL_LOGGER); | |||||
| // } | |||||
| // @Override | |||||
| // public void logException(StatementContext context, SQLException ex) { | |||||
| //// jdbi.setSqlLogger(SqlLogger.NOP_SQL_LOGGER); | |||||
| // } | |||||
| }); | |||||
| return jdbi.installPlugin(new SqlObjectPlugin()); | |||||
| } | |||||
| // @Bean | |||||
| // public Jdbi jdbi(DataSource ds, List<JdbiPlugin> jdbiPlugins, List<RowMapper<?>> rowMappers) { | |||||
| // TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(ds); | |||||
| // Jdbi jdbi = Jdbi.create(proxy); | |||||
| // jdbiPlugins.forEach(plugin -> jdbi.installPlugin(plugin)); | |||||
| // rowMappers.forEach(mapper -> jdbi.registerRowMapper(mapper)); | |||||
| // return jdbi; | |||||
| // } | |||||
| @Bean | |||||
| public HardwareDAO hardwareDAO(Jdbi jdbi) { | |||||
| return jdbi.onDemand(HardwareDAO.class); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package com.moze.rms.controller; | |||||
| import com.moze.rms.dao.HardwareDAO; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.web.bind.annotation.GetMapping; | |||||
| import org.springframework.web.bind.annotation.RequestMapping; | |||||
| import org.springframework.web.bind.annotation.RestController; | |||||
| @RestController | |||||
| @RequestMapping("/api/hardware") | |||||
| public class HardwareController { | |||||
| @Autowired | |||||
| HardwareDAO hardwareDAO; | |||||
| @GetMapping("/hardwares") | |||||
| public JsonResult getHardwares() { | |||||
| return new JsonResult(StatusCode.SUCCESS, hardwareDAO.findAll()); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package com.moze.rms.controller; | |||||
| import lombok.Data; | |||||
| import lombok.NoArgsConstructor; | |||||
| @Data | |||||
| @NoArgsConstructor | |||||
| public class JsonResult { | |||||
| private int code; | |||||
| private String message; | |||||
| private Object data; | |||||
| public JsonResult(StatusCode statusCode, Object data) { | |||||
| this.code = statusCode.getCode(); | |||||
| this.message = statusCode.getMessage(); | |||||
| this.data = data; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,55 @@ | |||||
| package com.moze.rms.controller; | |||||
| public enum StatusCode { | |||||
| /** 成功 */ | |||||
| SUCCESS(200, "成功"), | |||||
| /** 沒有登入 */ | |||||
| NOT_LOGIN(400, "帳號或密碼錯誤"), | |||||
| /** 發生異常 */ | |||||
| EXCEPTION(401, "發生異常"), | |||||
| /** 系統錯誤 */ | |||||
| SYS_ERROR(402, "系統錯誤"), | |||||
| /** 引數錯誤 */ | |||||
| PARAMS_ERROR(403, "引數錯誤 "), | |||||
| /** 不支援或已經廢棄 */ | |||||
| NOT_SUPPORTED(410, "不支援或已經廢棄"), | |||||
| /** AuthCode錯誤 */ | |||||
| INVALID_AUTHCODE(444, "無效的AuthCode"), | |||||
| /** 太頻繁的呼叫 */ | |||||
| TOO_FREQUENT(445, "太頻繁的呼叫"), | |||||
| /** 未知的錯誤 */ | |||||
| UNKNOWN_ERROR(499, "未知錯誤"); | |||||
| private int code; | |||||
| private String message; | |||||
| StatusCode(int code, String message) { | |||||
| this.code = code; | |||||
| this.message = message; | |||||
| } | |||||
| public int getCode() { | |||||
| return code; | |||||
| } | |||||
| public void setCode(int code) { | |||||
| this.code = code; | |||||
| } | |||||
| public String getMessage() { | |||||
| return message; | |||||
| } | |||||
| public void setMessage(String message) { | |||||
| this.message = message; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package com.moze.rms.dao; | |||||
| import com.moze.rms.entity.model.Hardware; | |||||
| import org.jdbi.v3.sqlobject.config.RegisterBeanMapper; | |||||
| import org.jdbi.v3.sqlobject.statement.SqlQuery; | |||||
| import org.springframework.stereotype.Repository; | |||||
| import java.util.List; | |||||
| @RegisterBeanMapper(Hardware.class) | |||||
| public interface HardwareDAO { | |||||
| @SqlQuery("select * from hardware;") | |||||
| List<Hardware> findAll(); | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package com.moze.rms.entity.model; | |||||
| import lombok.Data; | |||||
| import lombok.NoArgsConstructor; | |||||
| @Data | |||||
| @NoArgsConstructor | |||||
| public class Hardware { | |||||
| private String hostname; | |||||
| private String type; | |||||
| private String descript; | |||||
| private String ip1; | |||||
| private String ip2; | |||||
| private String model; | |||||
| private String environment; | |||||
| private String position; | |||||
| private String position_number; | |||||
| private Integer amount; | |||||
| private String owner_department; | |||||
| private String keep_department; | |||||
| private String keeper; | |||||
| private String remark; | |||||
| } | |||||
| @@ -1,6 +1,8 @@ | |||||
| server.servlet.context-path=/ | server.servlet.context-path=/ | ||||
| spring.datasource.url=jdbc:postgresql:// | |||||
| spring.datasource.username= | |||||
| spring.datasource.password= | |||||
| spring.datasource.url=jdbc:postgresql://172.105.222.191:54132/rms | |||||
| spring.datasource.username=moze | |||||
| spring.datasource.password=moze794064,! | |||||
| @@ -1,3 +1,3 @@ | |||||
| spring.datasource.url=jdbc:postgresql:// | |||||
| spring.datasource.username= | |||||
| spring.datasource.password= | |||||
| spring.datasource.url=jdbc:postgresql://172.105.222.191:54132/rms | |||||
| spring.datasource.username=moze | |||||
| spring.datasource.password=moze794064,! | |||||