Browse Source

202103260833

master
teddyhuang 5 years ago
parent
commit
312de6d48f
11 changed files with 421 additions and 253 deletions
  1. +264
    -0
      app/src/components/AccountManage.vue
  2. +4
    -2
      app/src/components/AssetGroup.vue
  3. +4
    -19
      app/src/components/Home.vue
  4. +0
    -220
      app/src/components/MockSearch.vue
  5. +10
    -8
      app/src/components/Search.vue
  6. +6
    -2
      app/src/router/index.js
  7. +46
    -0
      src/main/java/com/moze/rms/controller/AccountController.java
  8. +7
    -1
      src/main/java/com/moze/rms/controller/StatusCode.java
  9. +57
    -0
      src/main/java/com/moze/rms/dao/AccountDAO.java
  10. +22
    -0
      src/main/java/com/moze/rms/entity/model/Account.java
  11. +1
    -1
      src/main/java/com/moze/rms/utils/ExcelExpoter.java

+ 264
- 0
app/src/components/AccountManage.vue View File

@@ -0,0 +1,264 @@
<template>
<div>
<v-dialog
v-model="progress"
persistent
width="300"
>
<v-card
color="primary"
dark
>
<v-card-text>
載入中...
<v-progress-linear
indeterminate
color="white"
class="mb-0"
></v-progress-linear>
</v-card-text>
</v-card>
</v-dialog>
<v-data-table class="" :headers="headers" :items="items"
disable-sort
fixed-header
:footer-props="{'items-per-page-options': [30, 40, 50, 60]}"
:items-per-page="30">
<template v-slot:top>
<v-toolbar flat>
<v-toolbar-title class="title font-weight-bold">帳號管理</v-toolbar-title>
<v-divider
class="mx-4"
inset
vertical
/>
<v-spacer/>
<!--新增對話-->
<v-dialog
v-model="dialogInsert"
@click:outside="close"
max-width="500"
>

<template v-slot:activator="{ on, attrs }">
<v-btn
color="white"
class="primary"
v-bind="attrs"
v-on="on"
icon
>
<v-icon>mdi-plus</v-icon>
</v-btn>

</template>
<v-card>
<v-card-title>
<span class="headline font-weight-bold">新增</span>
</v-card-title>
<v-card-text>
<v-container>
<v-text-field v-model="insertItem.id" outlined rounded label="員工編號" />
<v-text-field v-model="insertItem.username" outlined rounded label="姓名" />
<v-select v-model="insertItem.department" outlined rounded :items="departments" label="部門"/>
<v-text-field v-model="insertItem.account" outlined rounded label="帳號" />
<v-text-field v-model="insertItem.pwd" outlined rounded label="密碼" />
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="close"
>
取消
</v-btn>
<v-btn
color="blue darken-1"
text
@click="checkIdAndAccountRepeat(insertItem, '新增')"
>
新增
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:item.actions="{ item }">
<div class="d-flex">
<v-btn
icon
@click="openDialogModify(item)"
>
<v-icon>mdi-pencil</v-icon>
</v-btn>
<v-icon
small
@click="deleteOne(item)"
>
mdi-delete
</v-icon>
</div>
</template>
</v-data-table>
<!--修改對話-->
<v-dialog
v-model="dialogModify"
@click:outside="close"
:retain-focus="false"
max-width="500"
>
<v-card>
<v-card-title>
<span class="headline font-weight-bold">修改</span>
</v-card-title>
<v-card-text>
<v-container>
<v-text-field v-model="modifyItem.id" outlined rounded label="員工編號" />
<v-text-field v-model="modifyItem.username" outlined rounded label="姓名" />
<v-select v-model="modifyItem.department" outlined rounded :items="departments" label="部門"/>
<v-text-field v-model="modifyItem.account" outlined rounded label="帳號" />
<v-text-field v-model="modifyItem.pwd" outlined rounded label="密碼" />
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="close"
>
取消
</v-btn>
<v-btn
color="blue darken-1"
text
@click="checkIdAndAccountRepeat(modifyItem, '修改')"
>
修改
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
name: '',
data() {
return {
fullHeight: 0,
dialogInsert: false,
dialogModify: false,
headers: [{'text': '', 'value': 'actions', fixed: true, sortable: false},
{'text': '員工編號', 'value': 'id'},
{'text': '姓名', 'value': 'username'},
{'text': '部門', 'value': 'department'},
// {'text': '型態', 'value': 'type'},
{'text': '帳號', 'value': 'account'},
{'text': '密碼', 'value': 'pwd'}],
items: [],
departments: [],
insertItem: {
account: "",
department: "",
level: "",
pwd: "",
username: "",
id: "",
},
modifyItem: {
account: "",
department: "",
level: "",
pwd: "",
username: "",
id: "",
},
progress: false,
}
},
async mounted() {
this.progress = true;
this.getUsers();
// this.getSelectItem();
this.fullHeight = window.innerHeight;
window.onresize = () => {
this.fullHeight = window.innerHeight;
};
this.getDepartments();
},
computed: {
},
watch: {
},
methods: {
openDialogModify(item) {
console.log(item.department);
this.modifyItem.username = item.username;
this.modifyItem.department = item.department;
this.modifyItem.account = item.account;
this.modifyItem.pwd = item.pwd;
this.modifyItem.level = item.level;
this.modifyItem.id = item.id;
this.dialogModify = true;
},
async getUsers() {
await this.$axios.get(`/account/accounts`)
.then((resp) => {
this.items = [];
this.items = resp.data.data;
this.progress = false;
});
},
async getDepartments() {
await this.$axios.get(`/account/departments`).then((resp) => {
this.departments = resp.data.data;
});
},
checkIdAndAccountRepeat(item, next) {
this.$axios.get(`/account/checkIdAndAccountRepeat?id=${item.id}&&account=${item.account}`).then((resp) => {
if (resp.data.code !== 200) {
alert(resp.data.message);
} else {
if (next === '新增') {
this.insertOne();
} else {
this.modifyOne();
}
}
});
},
insertOne() {
this.$axios.post(`/account/account`, this.insertItem).then(() => {
delete this.insertItem.tablename;
this.getUsers();
this.close();
}
);
},
modifyOne() {
this.$axios.put(`/account/account`, this.modifyItem).then(() => {
this.getUsers();
this.close();
}
);
},
deleteOne(item) {
let yes = confirm('確定刪除');
if (yes) {
this.$axios.delete(`/account/account?id=${item.id}`).then(() => {
this.getUsers();
alert('已刪除');
});
}
},
close() {
this.dialogInsert = false;
this.dialogModify = false;
},
}
}
</script>

+ 4
- 2
app/src/components/AssetGroup.vue View File

@@ -514,8 +514,8 @@
{'text': '文字框或選項', 'value': 'isselect'}, {'text': '文字框或選項', 'value': 'isselect'},
{'text': '順序', 'value': 'index'}, {'text': '順序', 'value': 'index'},
{'text': '必填', 'value': 'isrequire'}, {'text': '必填', 'value': 'isrequire'},
{'text': '可匯出', 'value': 'isexport'},
{'text': '可搜尋', 'value': 'issearch'},
// {'text': '可匯出', 'value': 'isexport'},
// {'text': '可搜尋', 'value': 'issearch'},
], ],
allCols: [], allCols: [],
insertColItem: { insertColItem: {
@@ -689,6 +689,8 @@
}); });
}, },
insertCol() { insertCol() {
this.insertColItem.issearch = 'true';
this.insertColItem.isexport = 'true';
for (const key in this.insertColItem) { for (const key in this.insertColItem) {
if (this.insertColItem[key] === '' && key !== 'tablename') { if (this.insertColItem[key] === '' && key !== 'tablename') {
console.log(key); console.log(key);


+ 4
- 19
app/src/components/Home.vue View File

@@ -180,25 +180,6 @@
], ],
} }
}, },
// data: () => ({
// dialog: false,
// drawer: null,
// error: false,
// message: "",
// items: [{text: '資訊資產群組', route: '/asset_group'}],
// username: localStorage.getItem('username'),
// this1: this,
// menuitems: [
// {
// icon: 'mdi-exit-to-app',
// href: '#',
// title: '登出',
// click: () => {
// this.logout();
// },
// },
// ],
// }),
created() { created() {
this.$root.$on('showError', (message) => { this.$root.$on('showError', (message) => {
this.error = true; this.error = true;
@@ -225,7 +206,11 @@
route.text = item.descript; route.text = item.descript;
route.route = `/inventory/${item.tablename}`; route.route = `/inventory/${item.tablename}`;
this.items.push(route); this.items.push(route);

}); });
if (localStorage.getItem('level') === '0') {
this.items.push({'text': '帳號管理', 'route': '/account'});
}
console.log(this.items); console.log(this.items);
}); });
}, },


+ 0
- 220
app/src/components/MockSearch.vue View File

@@ -1,220 +0,0 @@
<template>
<div>
<div>
<v-row justify="center" dense class="mt-1">
<v-col cols="4">
<v-text-field outlined rounded>
<template v-slot:append>
<v-icon @click="show = true">mdi-magnify</v-icon>
</template>
</v-text-field>
</v-col>
</v-row>
<v-toolbar flat v-if="show === true">
<v-toolbar-title>搜尋結果</v-toolbar-title>
<v-tabs
v-model='currentTab'
centered
show-arrows
style="width: 80%"
>
<v-tab
v-for='item in assertGroup'
:key='item.text'
class=' font-weight-bold'

>
<v-icon small>{{ item.text }}</v-icon>
</v-tab>

<v-tabs-items v-model='currentTab'>
<v-tab-item
v-for='cols in inventoryItems'
:key='cols.index'
>
<v-data-table
:items='cols'
:headers='headers'
hide-default-footer
>
</v-data-table>
</v-tab-item>
</v-tabs-items>
</v-tabs>
<v-btn
color="white"
class="primary mr-5"
@click="exportFile"
icon
>
<v-icon >mdi-file-export-outline</v-icon>
</v-btn>
</v-toolbar>
</div>
</div>
</template>
<script>
export default {
name: '',
data() {
return {
dialogInsert: false,
dialogModify: false,
dialogNewAssertGroup: false,
// dialogSearch: false,
title: '資訊資產群組',
headers: [
{'text': '中文名稱', 'value': 'descript'},
{'text': '資料庫欄位名稱', 'value': 'colname'},
{'text': '型態', 'value': 'type'},
{'text': '文字框或選項', 'value': 'select'},
{'text': '順序', 'value': 'index'},
{'text': '必填', 'value': 'require'},
{'text': '', 'value': 'actions', sortable: false}
],
inventoryItems: [],
insertCol: {
'tablename': '',
'colname': '',
'level': null,
'descript': '',
'type': '',
'select': '',
'search': '',
'export': '',
'require': ''
},
modifyCol: {},
assertGroup: [],
currentTab: 0,
types: [],
// selectItem: {},
// searchItem: {},
assertGroupDescript: '',
assertGroupTablename: '',
show: false,
}
},
async mounted() {
// this.getSelectItem();
this.getTabs();
this.getTypes();
this.inventoryItems = [];
this.getInventoryItem();
},
computed: {},
watch: {
currentTab() {
// // this.getTabs();
console.log(this.assertGroup[this.currentTab].value);
this.getTypes();
this.getInventoryItem();
},
},
methods: {
log(col) {
console.log(col);
},
oninput(item, key, val) {
this.$set(item, key, val);
},
getTabs() {
this.$axios.get(`/assert/assertGroups`).then((resp) => {
resp.data.data.forEach((item) => {
let header = {'text': null, 'value': null};
header.text = item.descript;
header.value = item.tablename;
this.assertGroup.push(header);
});
// this.assertGroup.push({'text': 'mdi-plus', 'value': ''});
});
},
getTypes() {
const tablename = this.assertGroup[this.currentTab] ? this.assertGroup[this.currentTab].value : 'hardware';
this.$axios.get(`/assert/Types?tablename=${tablename}`).then((resp) => {
this.types = resp.data.data;
});
},
getInventoryItem() {
const tablename = this.assertGroup[this.currentTab] ? this.assertGroup[this.currentTab].value : 'hardware';
this.$axios.get(`/assert/InventoryItems?tablename=${tablename}`).then((resp) => {
this.inventoryItems = resp.data.data;
});
},
insertOne() {
this.insertItem.tablename = this.tablename;
this.$axios.post(`/inventory?`, this.insertItem).then(() => {
delete this.insertItem.tablename;
this.getInventories();
this.close();
}
);
},
close() {
this.dialogInsert = false;
this.dialogModify = false;
this.dialogNewAssertGroup = false;
},
isDisabled(key) {
const disabledKey = ['id'];
return disabledKey.indexOf(key) >= 0;
},
isTextField(key) {
return this.select.indexOf(key) < 0;
},
isSelect(key) {
return this.select.indexOf(key) >= 0;
},
isRequire(key) {
return this.required.indexOf(key) >= 0;
},
getSelectItem() {
this.$axios.get(`/selectItem?tablename=${this.tablename}`).then((resp) => {
this.selectItem = resp.data.data;
});
},
modifyOne(item) {
item.tablename = this.tablename;
this.$axios.put(`/inventory?`, item).then(() => {
this.getInventories();
this.close();
}
);
},
deleteOne(item) {
let yes = confirm('確定刪除');
if (yes) {
this.$axios.delete(`/deleteOne?tablename=${this.tablename}&&id=${item.id}`).then(() => {
this.getInventories();
alert('已刪除');
});
}
console.log(item);
},
exportFile() {
let yes = confirm('確定匯出');
if (yes) {
// this.$axios.delete(`/deleteOne?tablename=${this.tablename}&&id=${item.id}`).then(() => {
// this.getInventories();
// });

}

},
mockInsertAssertGroup() {
// this.$axios.get(`/assert/assertGroups`).then((resp) => {
// resp.data.data.forEach((item) => {
// let header = {'text': null, 'value': null};
// header.text = item.descript;
// header.value = item.tablename;
// this.assertGroup.push(header);
// });
this.assertGroup.push({'text': this.assertGroupDescript, 'value': this.assertGroupTablename});
console.log(this.assertGroup);
// });
this.close();
},

}
}
</script>

+ 10
- 8
app/src/components/Search.vue View File

@@ -19,20 +19,22 @@
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-dialog> </v-dialog>
<v-row justify="center" dense class="ma-0 pa-0">
<v-col cols="4">
<v-text-field v-model="text" dense outlined prepend-inner-icon="mdi-magnify" hide-details rounded v-on:keyup.enter="search"/>
</v-col>
</v-row>
<v-toolbar flat v-if="result !== null">
<v-toolbar-title class="title font-weight-bold">搜尋結果</v-toolbar-title>

<v-toolbar flat >
<v-toolbar-title class="title font-weight-bold" v-if="result !== null">搜尋結果</v-toolbar-title>
<v-divider <v-divider
v-if="result !== null"
class="mx-4" class="mx-4"
inset inset
vertical vertical
/> />
<v-spacer/>
<v-row justify="start" dense class="ma-0 pa-0">
<v-col cols="4">
<v-text-field v-model="text" dense outlined prepend-inner-icon="mdi-magnify" hide-details rounded v-on:keyup.enter="search"/>
</v-col>
</v-row>
<v-btn <v-btn
v-if="result !== null"
color="white" color="white"
class="primary mr-5" class="primary mr-5"
@click="exportFile" @click="exportFile"


+ 6
- 2
app/src/router/index.js View File

@@ -5,8 +5,7 @@ import Home from '../components/Home';
import AssetGroup from '../components/AssetGroup'; import AssetGroup from '../components/AssetGroup';
import Inventory from '../components/Inventory'; import Inventory from '../components/Inventory';
import Search from '../components/Search'; import Search from '../components/Search';
// import MockSearch from '../components/MockSearch';

import account from '../components/AccountManage';
Vue.use(Router); Vue.use(Router);


export const constantRoutes = [ export const constantRoutes = [
@@ -35,6 +34,11 @@ export const constantRoutes = [
name: 'search', name: 'search',
component: Search component: Search
}, },
{
path: 'account',
name: 'account',
component: account
},
] ]
} }
]; ];


+ 46
- 0
src/main/java/com/moze/rms/controller/AccountController.java View File

@@ -2,6 +2,7 @@ package com.moze.rms.controller;




import com.moze.rms.dao.AccountDAO; import com.moze.rms.dao.AccountDAO;
import com.moze.rms.entity.model.Account;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;


@@ -28,4 +29,49 @@ public class AccountController {
public JsonResult logout() { public JsonResult logout() {
return new JsonResult(StatusCode.SUCCESS, null); return new JsonResult(StatusCode.SUCCESS, null);
} }

@GetMapping("/accounts")
public JsonResult getAccounts() {

return new JsonResult(StatusCode.SUCCESS, accountDAO.findAll());
}

@GetMapping("/checkIdAndAccountRepeat")
public JsonResult checkIdAndAccountRepeat(String id, String account) {
Integer a = accountDAO.findById(id);
Integer b = accountDAO.findByAccount(account);

if(a > 0) {
return new JsonResult(StatusCode.DUPLICATE_ID, null);
}else if (b > 0) {
return new JsonResult(StatusCode.DUPLICATE_ACCOUNT, null);
}else {
return new JsonResult(StatusCode.SUCCESS, null);
}
}

@PostMapping("/account")
public JsonResult insertAccount(@RequestBody Account account) {
accountDAO.insertOne(account);
return new JsonResult(StatusCode.SUCCESS, null);
}

@PutMapping("/account")
public JsonResult modifyAccount(@RequestBody Account account) {
accountDAO.modifyOne(account);
return new JsonResult(StatusCode.SUCCESS, null);
}

@DeleteMapping("/account")
public JsonResult deleteAccount(@RequestParam String id) {
accountDAO.deleteOne(id);
return new JsonResult(StatusCode.SUCCESS, null);
}

@GetMapping("/departments")
public JsonResult getDepartments() {

return new JsonResult(StatusCode.SUCCESS, accountDAO.finfDepartments());
}

} }

+ 7
- 1
src/main/java/com/moze/rms/controller/StatusCode.java View File

@@ -27,7 +27,13 @@ public enum StatusCode {
TOO_FREQUENT(445, "太頻繁的呼叫"), TOO_FREQUENT(445, "太頻繁的呼叫"),


/** 未知的錯誤 */ /** 未知的錯誤 */
UNKNOWN_ERROR(499, "未知錯誤");
UNKNOWN_ERROR(499, "未知錯誤"),

DUPLICATE_ID(420, "員工編號重複"),

DUPLICATE_ACCOUNT(421, "帳號重複");




private int code; private int code;
private String message; private String message;


+ 57
- 0
src/main/java/com/moze/rms/dao/AccountDAO.java View File

@@ -1,10 +1,12 @@
package com.moze.rms.dao; package com.moze.rms.dao;


import com.moze.rms.entity.model.Account;
import org.jdbi.v3.core.Handle; import org.jdbi.v3.core.Handle;
import org.jdbi.v3.sqlobject.SqlObject; import org.jdbi.v3.sqlobject.SqlObject;
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper; import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
import org.jdbi.v3.sqlobject.statement.SqlQuery; import org.jdbi.v3.sqlobject.statement.SqlQuery;


import java.util.List;
import java.util.Map; import java.util.Map;


public interface AccountDAO extends SqlObject { public interface AccountDAO extends SqlObject {
@@ -15,4 +17,59 @@ public interface AccountDAO extends SqlObject {
String sql = "select * from account where account = '" + account + "'"; String sql = "select * from account where account = '" + account + "'";
return handle.createQuery(sql).mapToMap().one(); return handle.createQuery(sql).mapToMap().one();
} }

@RegisterBeanMapper(Account.class)
@SqlQuery("select * from account order by id;")
List<Account> findAll();

@RegisterBeanMapper(List.class)
@SqlQuery("select * from department;")
List<String> finfDepartments();


default void insertOne(Account a) {

Handle handle = this.getHandle();

String sql = "insert into account(pwd, username, department, account, level, id) values (";

sql += "'" + a.getPwd() +"',";
sql += "'" + a.getUsername() +"',";
sql += "'" + a.getDepartment() +"',";
sql += "'" + a.getAccount() +"',";
sql += "'1',";
sql += "'" + a.getId() +"')";

handle.createUpdate(sql).execute();
}

default void modifyOne(Account a) {

Handle handle = this.getHandle();

String sql = "update account set ";
sql += "pwd = '" + a.getPwd() + "',";
sql += "username = '" + a.getUsername() + "',";
sql += "department = '" + a.getDepartment() + "',";
sql += "account = '" + a.getAccount() + "',";
sql += "level = '" + a.getLevel() + "'";
sql += "where id = '" + a.getId() + "'";

handle.createUpdate(sql).execute();
}

default void deleteOne(String id) {

Handle handle = this.getHandle();

String sql = "delete from account where id = '" + id + "'";

handle.createUpdate(sql).execute();
}

@SqlQuery("select count(*) from account where id = ?;")
Integer findById(String id);

@SqlQuery("select count(*) from account where account = ?;")
Integer findByAccount(String account);
} }

+ 22
- 0
src/main/java/com/moze/rms/entity/model/Account.java View File

@@ -0,0 +1,22 @@
package com.moze.rms.entity.model;


import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class Account {

private String id;

private String username;

private String account;

private String pwd;

private String department;

private String level;
}

+ 1
- 1
src/main/java/com/moze/rms/utils/ExcelExpoter.java View File

@@ -231,7 +231,7 @@ public class ExcelExpoter {


public void expoerDataExcelMultiSheet(HttpServletResponse response, Map<String, ArrayList<String>> titleKeyLists, Map<String, Map<String, String>> titleMaps, Map<String, List<Map<String, Object>>> src_lists, String filename) throws IOException { public void expoerDataExcelMultiSheet(HttpServletResponse response, Map<String, ArrayList<String>> titleKeyLists, Map<String, Map<String, String>> titleMaps, Map<String, List<Map<String, Object>>> src_lists, String filename) throws IOException {


String xlsFile_name = "資產清冊.xls"; //輸出xls檔名稱
String xlsFile_name = "SeverList.xls"; //輸出xls檔名稱
//記憶體中只建立100個物件 //記憶體中只建立100個物件
Workbook wb = new SXSSFWorkbook(100); //關鍵語句 Workbook wb = new SXSSFWorkbook(100); //關鍵語句
Iterator<Map.Entry<String, List<Map<String, Object>>>> iterator = src_lists.entrySet().iterator(); Iterator<Map.Entry<String, List<Map<String, Object>>>> iterator = src_lists.entrySet().iterator();


Loading…
Cancel
Save