|
- <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">{{title}}</v-toolbar-title>
- <v-divider
- class="mx-4"
- inset
- vertical
- />
- <div class="row align-center">
- <p v-if="haveSearch" class="mb-0 pa-0">搜尋條件:</p>
- <div v-for="(val, key, index) in searchItem" :key="index" class="pa-0 ma-0">
- <v-chip color="secondary" v-if="val !== null">
- {{mappingHeaders[key]}} 包含: {{val}}
- <v-icon @click="clearSinglePropInSearchItem(key)">mdi-close</v-icon>
- </v-chip>
- </div>
- </div>
- <v-spacer/>
- <!--匯入檔案對話-->
- <v-dialog
- v-model="dialogImport"
- @click:outside="close"
- :retain-focus="false"
- max-width="500"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-btn
- color="white"
- class="primary mr-5"
- v-bind="attrs"
- v-on="on"
- icon
- >
- <v-icon>mdi-file-import-outline</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>
- <div class="red--text text--lighten-3 d-flex">1.請確認<p class="font-weight-bold red--text text--lighten-1 mb-0">匯入之類別</p>相符</div>
- <div class="red--text text--lighten-3 d-flex">1.請確認<p class="font-weight-bold red--text text--lighten-1 mb-0">欄位名稱</p>一致</div>
- <div class="red--text text--lighten-3 d-flex">3.<p class="font-weight-bold red--text text--lighten-1">欄位順序</p>不影響匯入</div>
- <input id="file" type="file" @change="onFileChange" />
- </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="importFile"
- >
- 匯入
- </v-btn>
- </v-card-actions>
- </v-card>
- </v-dialog>
- <v-btn
- color="white"
- class="primary mr-5"
- @click="exportFile"
- icon
- >
- <v-icon>mdi-file-export-outline</v-icon>
- </v-btn>
- <!--搜尋對話-->
- <v-dialog
- v-model="dialogSearch"
- @click:outside="close"
- :retain-focus="false"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-btn
- color="white"
- class="primary mr-5"
- v-bind="attrs"
- v-on="on"
- icon
- >
- <v-icon>mdi-magnify</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-row>
- <v-col
-
- v-for="(header, index) in headers"
- :key="index"
- cols="12"
- sm="6"
- md="4"
- >
- <div v-if="headers[index] && headers[index].text !== '編號'">
- <v-text-field
- dense
- v-if="isTextField(header.value) && headers[index].text"
- :label="header.text"
- :disabled="isDisabled(header.value)"
- v-model="searchItem[header.value]"
- :persistent-hint="isRequire(header.value)"
- hint="必填"
- />
- <v-select
- dense
- v-if="isSelect(header.value) && headers[index].text"
- :persistent-hint="isRequire(header.value)"
- hint="必選"
- :label="header.text"
- v-model="searchItem[header.value]"
- :items="selectItem[header.value]"
- item-text="item"
- item-value="item"
- />
- </div>
- </v-col>
- </v-row>
- </v-container>
- </v-card-text>
- <v-card-actions>
- <v-spacer></v-spacer>
- <v-btn
- color="blue darken-1"
- text
- @click="clearSearchItem"
- >
- 清空
- </v-btn>
- <v-btn
- color="blue darken-1"
- text
- @click="close"
- >
- 關閉
- </v-btn>
- <v-btn
- color="blue darken-1"
- text
- @click="search"
- >
- 搜尋
- </v-btn>
- </v-card-actions>
- </v-card>
- </v-dialog>
- <!--新增對話-->
- <v-dialog
- v-model="dialogInsert"
- @click:outside="close"
- >
- <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-row>
- <v-col
-
- v-for="(header, index) in headers"
- :key="index"
- cols="12"
- sm="6"
- md="4"
- >
- <div v-if="headers[index] && headers[index].text !== '編號'">
- <v-text-field
- dense
- v-if="isTextField(header.value) && headers[index].text"
- :label="header.text"
- :disabled="isDisabled(header.value)"
- v-bind:value="insertItem[header.value]"
- :persistent-hint="isRequire(header.value)"
- hint="必填"
- v-on:input="oninput(insertItem, header.value, $event)"
- />
- <v-select
- dense
- v-if="isSelect(header.value) && headers[index].text"
- :persistent-hint="isRequire(header.value)"
- hint="必選"
- :label="header.text"
- :value="insertItem[header.value]"
- v-on:input="oninput(insertItem, header.value, $event)"
- :items="selectItem[header.value]"
- item-text="item"
- item-value="item"
- />
- </div>
- </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"
- >
- 取消
- </v-btn>
- <v-btn
- color="blue darken-1"
- text
- @click="insertOne"
- >
- 新增
- </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"
- >
- <v-card>
- <v-card-title>
- <span class="headline font-weight-bold">修改</span>
- </v-card-title>
- <v-card-text>
- <v-container>
- <v-row>
- <v-col
-
- v-for="(header, index) in headers"
- :key="index"
- cols="12"
- sm="6"
- md="4"
- >
- <div v-if="headers[index] && headers[index].text !== '編號'">
- <v-text-field
- dense
- v-if="isTextField(header.value) && headers[index].text"
- :label="header.text"
- :disabled="isDisabled(header.value)"
- v-bind:value="modifyItem[header.value]"
- :persistent-hint="isRequire(header.value)"
- hint="必填"
- v-on:input="oninput(modifyItem, header.value, $event)"
- />
- <v-select
- dense
- v-if="isSelect(header.value) && headers[index].text"
- :persistent-hint="isRequire(header.value)"
- hint="必選"
- :label="header.text"
- :value="modifyItem[header.value]"
- v-on:input="oninput(modifyItem, header.value, $event)"
- :items="selectItem[header.value]"
- item-text="item"
- item-value="item"
- />
- </div>
- </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"
- >
- 取消
- </v-btn>
- <v-btn
- color="blue darken-1"
- text
- @click="modifyOne(item)"
- >
- 修改
- </v-btn>
- </v-card-actions>
- </v-card>
- </v-dialog>
- </div>
- </template>
- <script>
- export default {
- name: '',
- data() {
- return {
- fullHeight: 0,
- dialogInsert: false,
- dialogModify: false,
- dialogSearch: false,
- title: '',
- headers: [],
- mappingHeaders: {},
- cols: {},
- items: [],
- isselect: [],
- isrequired: [],
- insertItem: {},
- modifyItem: {},
- selectItem: {},
- searchItem: {},
- mockSearch: false,
- haveSearch:false,
- dialogImport: false,
- file: null,
- progress: false,
- }
- },
- async mounted() {
- this.progress = true;
- this.getHeaders();
- this.getInventories();
- this.getTitle();
- this.getSelectItem();
- this.fullHeight = window.innerHeight;
- window.onresize = () => {
- this.fullHeight = window.innerHeight;
- };
- },
- computed: {
- tablename() {
- return this.$route.params.tablename;
- },
- },
- watch: {
- async tablename() {
- if (this.$route.params.tablename) {
- this.haveSearch = false;
- this.progress = true;
- this.title = '';
- await this.getHeaders();
- await this.getInventories();
- await this.getTitle();
- await this.getSelectItem();
- }
- },
- },
- methods: {
- log() {
- alert('as');
- },
- openDialogModify(item) {
- this.modifyItem = JSON.parse(JSON.stringify(item));
- this.dialogModify = true;
- },
- oninput(item, key, val) {
- this.$set(item, key, val);
- },
- async getTitle() {
- await this.$axios.get(`/title?tablename=${this.tablename}`).then((resp) => {
- this.title = `${resp.data.data}類`;
- });
- },
- async getHeaders() {
- await this.$axios.get(`/headers?tablename=${this.tablename}`)
- .then((resp) => {
- this.headers = [];
- this.headers.push({'text': '', 'value': 'actions', sortable: false});
- this.insertItem = {};
- this.searchItem = {};
- this.cols = resp.data.data;
- resp.data.data.forEach((item) => {
- let header = {'text': null, 'value': null};
- header.text = item.descript;
- header.value = item.colname;
- this.mappingHeaders[item.colname] = item.descript;
- this.headers.push(header);
- if (item.isselect === 'true') {
- this.isselect.push(item.colname);
- }
- if (item.isrequire === 'true') {
- this.isrequired.push(item.colname);
- }
- this.insertItem[item.colname] = null;
- this.searchItem[item.colname] = null;
- });
- });
- },
- async getInventories() {
-
- await this.$axios.get(`/inventory?tablename=${this.tablename}`)
- .then((resp) => {
- this.items = [];
- this.items = resp.data.data;
- this.progress = false;
- });
- },
- async getSelectItem() {
-
- await this.$axios.get(`/selectItem?tablename=${this.tablename}`).then((resp) => {
- this.selectItem = {};
- this.selectItem = resp.data.data;
- });
- },
- insertOne() {
- this.insertItem.tablename = this.tablename;
- this.$axios.post(`/inventory?`, this.insertItem).then(() => {
- delete this.insertItem.tablename;
- this.getInventories();
- this.close();
- alert('已新增');
- }
- );
- },
- close() {
- this.dialogInsert = false;
- this.dialogModify = false;
- this.dialogSearch = false;
- this.dialogImport = false;
- },
- isDisabled(key) {
- const disabledKey = ['id'];
- return disabledKey.indexOf(key) >= 0;
- },
- isTextField(key) {
- return this.isselect.indexOf(key) < 0;
- },
- isSelect(key) {
- return this.isselect.indexOf(key) >= 0;
- },
- isRequire(key) {
- return this.isrequired.indexOf(key) >= 0;
- },
- 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(() => {
- if (this.haveSearch === true) {
- this.search();
- } else {
- this.getInventories();
- }
- alert('已刪除');
- });
- }
- },
- search() {
- this.searchItem.tablename = this.tablename;
- this.$axios.post(`/search`, this.searchItem).then((resp) => {
- delete this.searchItem.tablename;
- this.items = resp.data.data;
- this.haveSearch = true;
- this.dialogSearch = false;
- });
- },
- clearSinglePropInSearchItem(key) {
- const self = this;
- this.searchItem[key] = null;
- this.haveSearch = false;
- Object.keys(this.searchItem).forEach(function(key){
- if (self.searchItem[key] && self.searchItem[key] !== null) {
- this.haveSearch = true;
- }
- });
- this.getInventories();
- },
- async clearSearchItem() {
- const self = this;
- Object.keys(this.searchItem).forEach(function(key){
- self.searchItem[key] = null;
- });
- this.getInventories();
- this.haveSearch = false;
- },
- onFileChange(e) {
- const files = e.target.files || e.dataTransfer.files;
- if (files.length > 0) {
- console.log(files[0].name);
- // eslint-disable-next-line prefer-destructuring
- this.file = files[0];
- }
- },
- importFile() {
- this.progress = true;
- const formData = new FormData();
- formData.append('tablename', this.tablename);
- formData.append('file', this.file);
- this.$axios.post(`/importFile`, formData).then(() => {
- document.getElementById('file').value = null;
- this.getInventories();
- this.file = null;
- this.progress = false;
- this.dialogImport = false;
- });
-
- },
- exportFile() {
- let yes = confirm('確定匯出');
- if (yes) {
- this.$axios.post(`/exportFile`, {items: this.items, info: {tablename: this.tablename}}, {responseType: 'blob'})
- .then((resp) => {
- console.log(resp.headers['filename']);
- const blob = new Blob([resp.data], {type: "application/vnd.ms-excel;charset=utf-8"});
- const reader = new FileReader();
- reader.readAsDataURL(blob);
- reader.onload = (e) => {
- const a = document.createElement('a');
- a.download = resp.headers['filename'];
- a.href = e.target.result;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- };
- }
- );
- }
- }
-
- }
- }
- </script>
|