|
|
@@ -1,122 +1,103 @@
|
|
|
-<!-- 發文資料管理 -->
|
|
|
<template>
|
|
|
+ <!-- 發文資料管理 -->
|
|
|
<div>
|
|
|
+ <!-- 功能欄 -->
|
|
|
+ <functionBar class="F_bar" @getList="getFileList"></functionBar>
|
|
|
<div>
|
|
|
- <functionBar class="F_bar" @getList="getFileList" />
|
|
|
- </div>
|
|
|
- <b-container fluid>
|
|
|
- <div style="margin-top: 80px">
|
|
|
- <b-row style="margin-top: 11px">
|
|
|
- <b-col cols="12">
|
|
|
- <div style="margin-left: 11.8vw; margin-top: 1.5vh; color: black; width: 55vw">
|
|
|
- <b-form-group
|
|
|
- label="關鍵字:"
|
|
|
- label-for="filter-input"
|
|
|
- label-cols="2"
|
|
|
- label-align="right"
|
|
|
- label-size="1px"
|
|
|
- >
|
|
|
- <b-input-group size="1px">
|
|
|
- <b-form-input
|
|
|
- id="filter-input"
|
|
|
- v-model="filter"
|
|
|
- type="search"
|
|
|
- placeholder="請輸入關鍵字"
|
|
|
- ></b-form-input>
|
|
|
- </b-input-group>
|
|
|
- </b-form-group>
|
|
|
- </div>
|
|
|
+ <div class="container" fluid></div>
|
|
|
+ <div style="margin-left: 12%; margin-top: 15px; color: black; width: 80%">
|
|
|
+ <b-row>
|
|
|
+ <!-- 篩選條件選項 -->
|
|
|
+ <b-col cols="2">
|
|
|
+ <div style="margin-top: 9px; text-align: right">篩選條件:</div>
|
|
|
+ </b-col>
|
|
|
+ <b-col cols="6">
|
|
|
+ <!-- 多選下拉框 -->
|
|
|
+ <multiselect
|
|
|
+ v-model="searchCondition.keyword"
|
|
|
+ tag-placeholder="加入欄位"
|
|
|
+ placeholder="可輸入檔案名稱或單位名稱"
|
|
|
+ :options="keywords"
|
|
|
+ :multiple="true"
|
|
|
+ :showNoOptions="false"
|
|
|
+ :taggable="true"
|
|
|
+ @tag="addTagKeyword"
|
|
|
+ ></multiselect>
|
|
|
+ </b-col>
|
|
|
+ <b-col cols="2">
|
|
|
+ <!-- 運算子選項 -->
|
|
|
+ <b-form-select v-model="searchCondition.operator" :options="operators"></b-form-select>
|
|
|
+ </b-col>
|
|
|
+ <b-col cols="2" style="padding: 0">
|
|
|
+ <b-button class="btn_search" style="float: left; margin-top: 4px" @click="filterList">篩選</b-button>
|
|
|
</b-col>
|
|
|
</b-row>
|
|
|
- <div>
|
|
|
- <b-row>
|
|
|
- <b-col>
|
|
|
- <!-- TABLE -->
|
|
|
- <b-table
|
|
|
- :items="relateFileList"
|
|
|
- :fields="fields"
|
|
|
- :filter="filter"
|
|
|
- thead-class="thClass"
|
|
|
- class="text-center"
|
|
|
- responsive="sm"
|
|
|
- striped
|
|
|
- bordered
|
|
|
- fixed
|
|
|
- :per-page="perPage"
|
|
|
- :current-page="currentPage"
|
|
|
- :sort-desc.sync="sortDesc"
|
|
|
- :sort-by.sync="sortBy"
|
|
|
- >
|
|
|
- <!-- HEAD -->
|
|
|
- <template #head()="{label, field: { key, sortable } }">
|
|
|
- <span
|
|
|
- style="font-weight: normal; color: white; font-size: 15px"
|
|
|
- >{{ label }}</span
|
|
|
- >
|
|
|
- <template v-if="sortable">
|
|
|
- <b-icon font-scale="1.3" v-if="sortBy !== key" icon="arrow-down-up"></b-icon>
|
|
|
- <b-icon font-scale="1.3" v-else-if="sortDesc" icon="arrow-down"></b-icon>
|
|
|
- <b-icon font-scale="1.3" v-else icon="arrow-up"></b-icon>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- <!-- BODY -->
|
|
|
- <!-- 序號 -->
|
|
|
- <template #cell(serial_number)="data">
|
|
|
- <span
|
|
|
- style="font-weight: normal; color: black; font-size: 15px"
|
|
|
- >
|
|
|
- {{ ( currentPage - 1 ) * perPage + data.index + 1 }}
|
|
|
- </span>
|
|
|
- </template>
|
|
|
- <!-- 檔案名稱 -->
|
|
|
- <template #cell(name)="data">
|
|
|
- <a
|
|
|
- style="font-weight: normal; color: blue; font-size: 15px"
|
|
|
- :href="data.item.src"
|
|
|
- target="_blank"
|
|
|
- >
|
|
|
- {{ data.value }}
|
|
|
- </a>
|
|
|
- </template>
|
|
|
- <!-- 上傳日期 -->
|
|
|
- <template #cell(postDay)="data">
|
|
|
- <span
|
|
|
- style="font-weight: normal; color: black; font-size: 15px"
|
|
|
- >
|
|
|
- {{ getFormattedDate(data.value) }}
|
|
|
- </span>
|
|
|
- </template>
|
|
|
- <!-- 類型 -->
|
|
|
- <template #cell(icon)="data">
|
|
|
-
|
|
|
- <img class="ml-3 m-0" style="width:30px;height:auto;display:inline-block" :src="data.item.icon">
|
|
|
- </template>
|
|
|
- <!-- 大小 -->
|
|
|
- <template #cell(size)="data">
|
|
|
- <span
|
|
|
- style="font-weight: normal; color: black; font-size: 15px"
|
|
|
- v-if="data.value / 1024 / 1024 > 1"
|
|
|
- >{{ (data.value / 1024 / 1024).toFixed(1) }} MB</span
|
|
|
- >
|
|
|
- <span v-else
|
|
|
- >{{ (data.value / 1024).toFixed(1) }} KB</span
|
|
|
- >
|
|
|
- </template>
|
|
|
- </b-table>
|
|
|
- <!-- 分頁符號 -->
|
|
|
- <b-pagination
|
|
|
- v-model="currentPage"
|
|
|
- pills
|
|
|
- :total-rows="rows"
|
|
|
- :per-page="perPage"
|
|
|
- aria-controls="my-table"
|
|
|
- >
|
|
|
- </b-pagination>
|
|
|
- </b-col>
|
|
|
- </b-row>
|
|
|
- </div>
|
|
|
</div>
|
|
|
- </b-container>
|
|
|
+ <div style="width:90%;overflow: auto;margin-left:80px;height:600px;margin-top: 50px;">
|
|
|
+ <!-- 表格 -->
|
|
|
+ <b-table
|
|
|
+ :items="relateFileList"
|
|
|
+ :fields="fields"
|
|
|
+ :filter="filter"
|
|
|
+ thead-class="thClass"
|
|
|
+ class="text-center"
|
|
|
+ ref="selectableTable"
|
|
|
+ responsive="sm"
|
|
|
+ striped
|
|
|
+ bordered
|
|
|
+ fixed
|
|
|
+ :per-page="perPage"
|
|
|
+ :current-page="currentPage"
|
|
|
+ :sort-desc.sync="sortDesc"
|
|
|
+ :sort-by.sync="sortBy"
|
|
|
+ sticky-header="577px"
|
|
|
+ >
|
|
|
+ <!-- 表頭 -->
|
|
|
+ <template #head()="{ label, field: { key, sortable } }">
|
|
|
+ <span style="font-weight: normal; color: white; font-size: 15px">{{ label }}</span>
|
|
|
+ <template v-if="sortable">
|
|
|
+ <b-icon font-scale="1.3" v-if="sortBy !== key" icon="arrow-down-up"></b-icon>
|
|
|
+ <b-icon font-scale="1.3" v-else-if="sortDesc" icon="arrow-down"></b-icon>
|
|
|
+ <b-icon font-scale="1.3" v-else icon="arrow-up"></b-icon>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <!-- 表身 -->
|
|
|
+ <!-- 序號 -->
|
|
|
+ <template #cell(serial_number)="data">
|
|
|
+ <span style="font-weight: normal; color: black; font-size: 15px">
|
|
|
+ {{ (currentPage - 1) * perPage + data.index + 1 }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ <!-- 檔案名稱 -->
|
|
|
+ <template #cell(name)="data">
|
|
|
+ <a style="font-weight: normal; color: blue; font-size: 15px" :href="data.item.src" target="_blank">
|
|
|
+ {{ data.value }}
|
|
|
+ </a>
|
|
|
+ </template>
|
|
|
+ <!-- 發文日期 -->
|
|
|
+ <template #cell(postDay)="data">
|
|
|
+ <span style="font-weight: normal; color: black; font-size: 15px">{{ getFormattedDate(data.value) }}</span>
|
|
|
+ </template>
|
|
|
+ <!-- 單位名稱 -->
|
|
|
+ <template #cell(department_classification)="data">
|
|
|
+ <span style="font-weight: normal; color: black; font-size: 15px">{{ data.value }}</span>
|
|
|
+ </template>
|
|
|
+ <!-- 類型 -->
|
|
|
+ <template #cell(icon)="data">
|
|
|
+ <img class="ml-3 m-0" style="width:30px;height:auto;display:inline-block" :src="data.item.icon">
|
|
|
+ </template>
|
|
|
+ <!-- 大小 -->
|
|
|
+ <template #cell(size)="data">
|
|
|
+ <span style="font-weight: normal; color: black; font-size: 15px" v-if="data.value / 1024 / 1024 > 1">
|
|
|
+ {{ (data.value / 1024 / 1024).toFixed(1) }} MB
|
|
|
+ </span>
|
|
|
+ <span v-else>{{ (data.value / 1024).toFixed(1) }} KB</span>
|
|
|
+ </template>
|
|
|
+ </b-table>
|
|
|
+ </div>
|
|
|
+ <!-- 分頁符號 -->
|
|
|
+ <b-pagination v-model="currentPage" pills :total-rows="rows" :per-page="perPage" aria-controls="my-table"></b-pagination>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -126,6 +107,7 @@ import { mapState, mapActions } from 'vuex'
|
|
|
import Multiselect from 'vue-multiselect'
|
|
|
import moment from 'moment'
|
|
|
import fileType from '@/util/fileType.js'
|
|
|
+import 'vue-multiselect/dist/vue-multiselect.min.css'
|
|
|
export default {
|
|
|
components: {
|
|
|
functionBar,
|
|
|
@@ -134,6 +116,7 @@ export default {
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
+ keywords: [],
|
|
|
filter: null,
|
|
|
selected: [],
|
|
|
perPage: 8,
|
|
|
@@ -146,49 +129,66 @@ export default {
|
|
|
label: '序號',
|
|
|
sortable: false,
|
|
|
tdClass: 'align-middle',
|
|
|
- thStyle: { background: '#1d325f', color: '#ffffff' }
|
|
|
+ thStyle: { background: '#1d325f', color: '#ffffff', width: '10%' }
|
|
|
},
|
|
|
{
|
|
|
key: 'name',
|
|
|
label: '檔案名稱',
|
|
|
sortable: false,
|
|
|
tdClass: 'align-middle',
|
|
|
- thStyle: { background: '#1d325f', color: '#ffffff' }
|
|
|
+ thStyle: { background: '#1d325f', color: '#ffffff', width: '30%' }
|
|
|
},
|
|
|
{
|
|
|
key: 'postDay',
|
|
|
label: '發文日期',
|
|
|
sortable: true,
|
|
|
tdClass: 'align-middle',
|
|
|
- thStyle: { background: '#1d325f', color: '#ffffff' }
|
|
|
+ thStyle: { background: '#1d325f', color: '#ffffff', width: '15%' }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'department_classification',
|
|
|
+ label: '單位名稱',
|
|
|
+ sortable: true,
|
|
|
+ tdClass: 'align-middle',
|
|
|
+ thStyle: { background: '#1d325f', color: '#ffffff', width: '20%' }
|
|
|
},
|
|
|
{
|
|
|
key: 'icon',
|
|
|
label: '類型',
|
|
|
sortable: false,
|
|
|
tdClass: 'align-middle',
|
|
|
- thStyle: { background: '#1d325f', color: '#ffffff' }
|
|
|
+ thStyle: { background: '#1d325f', color: '#ffffff', width: '15%' }
|
|
|
},
|
|
|
{
|
|
|
key: 'size',
|
|
|
label: '檔案大小',
|
|
|
sortable: false,
|
|
|
tdClass: 'align-middle',
|
|
|
- thStyle: { background: '#1d325f', color: '#ffffff' }
|
|
|
+ thStyle: { background: '#1d325f', color: '#ffffff', width: '10%' }
|
|
|
}
|
|
|
],
|
|
|
+ operators: [
|
|
|
+ { value: 'and', text: 'and' },
|
|
|
+ { value: 'or', text: 'or' }
|
|
|
+ ],
|
|
|
+ searchCondition: {
|
|
|
+ operator: 'and',
|
|
|
+ keyword: []
|
|
|
+ },
|
|
|
relateFileList: []
|
|
|
}
|
|
|
},
|
|
|
async mounted () {
|
|
|
await this.getPostFileManagement(this.currentUser.defaultTender)
|
|
|
+ await this.lookupTender(this.currentUser.defaultTender)
|
|
|
await this.getOtherList(this.currentUser.defaultTender)
|
|
|
this.getFileList()
|
|
|
console.log(this.relateFileList)
|
|
|
},
|
|
|
methods: {
|
|
|
- ...mapActions('tenders', ['getPostFileManagement', 'getOtherList']),
|
|
|
+ ...mapActions('tenders', ['getPostFileManagement', 'getOtherList', 'lookupPostFileSearch', 'lookupTender']),
|
|
|
getFormattedDate (date) {
|
|
|
+ // 轉換日期格式
|
|
|
let d = null
|
|
|
if (date) {
|
|
|
return moment(date).format('YYYY-MM-DD')
|
|
|
@@ -196,23 +196,50 @@ export default {
|
|
|
return d
|
|
|
}
|
|
|
},
|
|
|
+ addTagKeyword (newTag) {
|
|
|
+ this.searchCondition.keyword.push(newTag)
|
|
|
+ },
|
|
|
+ async filterList () {
|
|
|
+ if (this.searchCondition.keyword.length === 0) {
|
|
|
+ alert('輸入關鍵字')
|
|
|
+ } else {
|
|
|
+ let searchList = await this.lookupPostFileSearch({
|
|
|
+ operator: this.searchCondition.operator,
|
|
|
+ keyword:
|
|
|
+ this.searchCondition.keyword.length === 0
|
|
|
+ ? []
|
|
|
+ : this.searchCondition.keyword
|
|
|
+ })
|
|
|
+ if (searchList.length !== 0) {
|
|
|
+ this.relateFileList = searchList.map(item => ({
|
|
|
+ ...item,
|
|
|
+ icon: fileType(item.mime)
|
|
|
+ }))
|
|
|
+ } else {
|
|
|
+ this.relateFileList = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
async getFileList () {
|
|
|
this.relateFileList = []
|
|
|
for (let i = 0; i < this.postFileManagementList.length; i++) {
|
|
|
const element = this.postFileManagementList[i]
|
|
|
const docFile = element.docFile
|
|
|
+ const { name, mime, size, src } = docFile[0]
|
|
|
if (docFile && docFile.length > 0 && docFile[0].name) {
|
|
|
this.relateFileList.push({
|
|
|
_id: element._id,
|
|
|
- name: docFile[0].name,
|
|
|
postDay: element.postDay,
|
|
|
- mime: docFile[0].mime,
|
|
|
- size: docFile[0].size,
|
|
|
- src: docFile[0].src,
|
|
|
- icon: fileType(docFile[0].mime)
|
|
|
+ department_classification: element.department_classification,
|
|
|
+ name,
|
|
|
+ mime,
|
|
|
+ size,
|
|
|
+ src,
|
|
|
+ icon: fileType(mime)
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
+ console.log(this.relateFileList)
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
@@ -228,11 +255,12 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
watch: {
|
|
|
+ // 監視 postFileManagementList 的變動,當資料變動時,自動更新檔案列表
|
|
|
postFileManagementList: {
|
|
|
handler () {
|
|
|
this.getFileList()
|
|
|
},
|
|
|
- deep: true
|
|
|
+ deep: true // 監視所有層級的變動,如果檔案列表是嵌套的也會監視到
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -243,7 +271,6 @@ export default {
|
|
|
z-index: 999;
|
|
|
}
|
|
|
.thClass {
|
|
|
- font-size: 16px;
|
|
|
background-color: #1d325f;
|
|
|
color: white;
|
|
|
}
|
|
|
@@ -254,6 +281,77 @@ export default {
|
|
|
}
|
|
|
</style>
|
|
|
<style lang="scss" scoped>
|
|
|
+/deep/.popover{
|
|
|
+ padding: 10px;
|
|
|
+ max-width: 450px;
|
|
|
+ text-align: left;
|
|
|
+ background-color: white;
|
|
|
+}
|
|
|
+/deep/ .popover-header{
|
|
|
+ font-size: 18px;
|
|
|
+ color: black;
|
|
|
+}
|
|
|
+/deep/ .popover-body{
|
|
|
+ font-size: 16px;
|
|
|
+ color: black;
|
|
|
+}
|
|
|
+/deep/ .align-middle {
|
|
|
+ max-width: 200px;
|
|
|
+ white-space: normal !important;
|
|
|
+}
|
|
|
+/deep/ .truncate {
|
|
|
+ width: 50px;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+}
|
|
|
+.container {
|
|
|
+ height: 50px;
|
|
|
+ margin-top: 10px;
|
|
|
+ margin-left: 5%;
|
|
|
+ padding-top: 10px;
|
|
|
+ padding-left: 1%;
|
|
|
+ padding-right: 1%;
|
|
|
+}
|
|
|
+.text-center {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+.btns2 {
|
|
|
+ float: right;
|
|
|
+ margin-right: 5%;
|
|
|
+}
|
|
|
+.btn_refresh {
|
|
|
+ background-color: #f7fafc;
|
|
|
+ font-size: 14px;
|
|
|
+ padding-left: 7px;
|
|
|
+ padding-right: 7px;
|
|
|
+ padding-top: 5px;
|
|
|
+ padding-bottom: 5px;
|
|
|
+ margin-left: 10px;
|
|
|
+ color: #1d325f;
|
|
|
+ box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
|
|
|
+}
|
|
|
+.btn_refresh:hover {
|
|
|
+ color: black;
|
|
|
+ background-color: rgb(228, 228, 228);
|
|
|
+ transform: scale(1.1);
|
|
|
+}
|
|
|
+.btn_search {
|
|
|
+ background-color: rgb(75, 102, 255);
|
|
|
+ font-size: 15px;
|
|
|
+ padding-left: 10px;
|
|
|
+ padding-right: 10px;
|
|
|
+ padding-top: 6px;
|
|
|
+ padding-bottom: 6px;
|
|
|
+ color: white;
|
|
|
+ box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
|
|
|
+}
|
|
|
+.btn_search:hover {
|
|
|
+ color: black;
|
|
|
+ background-color: rgb(228, 228, 228);
|
|
|
+ transform: translateY(1);
|
|
|
+}
|
|
|
.pagination {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
@@ -262,14 +360,12 @@ export default {
|
|
|
margin-top: 20px;
|
|
|
color: #383838;
|
|
|
}
|
|
|
-/deep/ .align-middle {
|
|
|
- max-width: 400px;
|
|
|
- white-space: normal !important;
|
|
|
+.form-control {
|
|
|
+ color: black;
|
|
|
}
|
|
|
-/deep/ .truncate {
|
|
|
- width: 400px;
|
|
|
- white-space: nowrap;
|
|
|
- overflow: hidden;
|
|
|
- text-overflow: ellipsis;
|
|
|
+.custom-select {
|
|
|
+ color: black;
|
|
|
}
|
|
|
+.table thead th {
|
|
|
+ font-size: 15px;}
|
|
|
</style>
|