houzhongjian
2024-07-23 8501060c4f921d1e744c477e4dc08eb47b52693c
提交 | 用户 | 时间
850106 1 <template>
H 2   <el-card shadow="never" class="aui-card--fill">
3     <div class="mod-knowledge" style="height: 100%" v-loading="dataListLoading">
4       <div class="dev-type-main-left">
5         <div v-show="showRightMenu" v-if="$hasPermission('knowledge:det:update')">
6           <ul id="menu" class="right-menu" style="user-select: none">
7             <li class="menu-item" v-if="!isLastNode" @click="addNode(false)">新增目录</li>
8             <li class="menu-item" v-if="formData.parentId === '0000000000'" @click="addNode(true)">新增根目录</li>
9             <li class="menu-item" @click="updateNode">编辑</li>
10             <li class="menu-item" @click="deleteNode">删除</li>
11           </ul>
12         </div>
13       </div>
14       <el-dialog
15           :title="`${!isUpdate ? '新建' : '编辑'}`"
16           :visible.sync="dialogVisible"
17           width="30%"
18           :close-on-click-modal="false">
19         <el-form :model="form" :rules="dataRule" ref="form">
20           <el-form-item label="名称" prop="labelName" :rules="dataRule.labelName">
21             <el-input v-model="form.labelName" placeholder="输入节点名称"></el-input>
22           </el-form-item>
23         </el-form>
24         <span slot="footer" class="dialog-footer">
25         <el-button size="mini" @click="dialogVisible = false">取 消</el-button>
26         <el-button size="mini" type="primary" @click="dataFormSubmit">确 定</el-button>
27       </span>
28       </el-dialog>
29       <el-row style="height: 750px" @contextmenu.native="handleMouse">
30         <el-col :span="6" style="height: 100%; border: 1px solid lightgray;padding: 10px">
31           <el-row>
32             <el-col :span="16">
33               <el-input size="mini"
34                         placeholder="输入关键字过滤"
35                         v-model="filterText">
36               </el-input>
37             </el-col>
38             <el-col :span="8">
39               <el-button v-if="$hasPermission('knowledge:det:update')" size="mini" type="primary" style="margin-left: 5px;" @click="addNode(true)">新增根目录</el-button>
40             </el-col>
41           </el-row>
42           <el-tree
43               :data="data"
44               ref="tree"
45               node-key="id"
46               current-node-key
47               default-expand-all
48               :expand-on-click-node="false"
49               @node-click="handleNodeClick"
50               @node-contextmenu="rightClick"
51               :filter-node-method="filterNode"
52               :highlight-current="true"
53               style="user-select: none">
54           <span slot-scope="{ node, data }">
55             <i v-if="node.expanded && data.children.length > 0" class="el-icon-folder-opened"></i>
56             <i v-else class="el-icon-folder"></i>
57             <span>{{ node.label }}</span>
58           </span>
59           </el-tree>
60         </el-col>
61         <el-col :span="18" style="height: 100%">
62           <el-col :span="24" style="height: 100%; border: 1px solid lightgray; margin-left: 5px">
63             <el-row style="padding: 10px">
64               <el-col :span="24">
65                 <el-form :inline="true" :model="fileForm" ref="fileForm">
66                   <el-form-item prop="title">
67                     <el-input v-model="fileForm.title" placeholder="输入标题" clearable></el-input>
68                   </el-form-item>
69                   <el-form-item prop="keyWords">
70                     <el-input v-model="fileForm.keyWords" placeholder="输入关键词" clearable></el-input>
71                   </el-form-item>
72                   <el-form-item prop="content">
73                     <el-input v-model="fileForm.content" placeholder="输入摘要" clearable></el-input>
74                   </el-form-item>
75                   <el-form-item>
76                     <el-button @click="getTableList(chooseTreeId)">查询</el-button>
77                     <el-button v-if="$hasPermission('knowledge:det:update')" type="primary" @click="addOrUpdateHandle()">添加文件</el-button>
78                     <el-button v-if="$hasPermission('knowledge:det:delete')" type="danger" @click="deleteHandle()" :disabled="dataListSelections.length <= 0">批量删除
79                     </el-button>
80                   </el-form-item>
81                 </el-form>
82               </el-col>
83               <el-col>
84                 <el-table
85                     :data="tableList"
86                     v-loading="tableLoading"
87                     border
88                     @selection-change="selectionChangeHandle">
89                   <el-table-column
90                       type="selection"
91                       header-align="center"
92                       align="center"
93                       width="50">
94                   </el-table-column>
95                   <el-table-column
96                       type="index"
97                       header-align="center"
98                       align="center"
99                       width="50"
100                       label="序号">
101                   </el-table-column>
102                   <el-table-column
103                       prop="title"
104                       header-align="center"
105                       align="left"
106                       min-width="150"
107                       label="标题">
108                   </el-table-column>
109                   <el-table-column
110                       prop="keyWords"
111                       header-align="center"
112                       align="center"
113                       label="关键词">
114                   </el-table-column>
115                   <el-table-column
116                       prop="typeId"
117                       header-align="center"
118                       align="center"
119                       width="100"
120                       label="类型">
121                     <template slot-scope="scope">
122                       {{ $getDictLabel("knowledge-type", scope.row.typeId) }}
123                     </template>
124                   </el-table-column>
125                   <el-table-column
126                       prop="content"
127                       header-align="center"
128                       align="left"
129                       min-width="100"
130                       label="摘要">
131                   </el-table-column>
132                   <el-table-column
133                       header-align="center"
134                       align="center"
135                       width="120"
136                       label="操作">
137                     <template slot-scope="scope">
138                       <el-button type="text" size="small" @click="filePreview(scope.row)">预览</el-button>
139                       <span>|</span>
140                       <el-dropdown>
141                       <span class="el-dropdown-link">
142                         <el-button type="text" size="small">更多</el-button>
143                         <i class="el-icon-arrow-down el-icon--right"></i>
144                       </span>
145                         <el-dropdown-menu slot="dropdown">
146                           <el-dropdown-item v-if="$hasPermission('knowledge:det:update')">
147                             <el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">编辑
148                             </el-button>
149                           </el-dropdown-item>
150                           <el-dropdown-item>
151                             <el-button type="text" size="small" v-if="scope.row.url" @click="download(scope.row.url)">下载
152                             </el-button>
153                           </el-dropdown-item>
154                         </el-dropdown-menu>
155                       </el-dropdown>
156                     </template>
157                   </el-table-column>
158                 </el-table>
159                 <el-pagination
160                     @size-change="sizeChangeHandle"
161                     @current-change="currentChangeHandle"
162                     :current-page="pageIndex"
163                     :page-sizes="[10, 20, 50, 100]"
164                     :page-size="pageSize"
165                     :total="totalPage"
166                     layout="total, sizes, prev, pager, next, jumper">
167                 </el-pagination>
168               </el-col>
169             </el-row>
170           </el-col>
171         </el-col>
172       </el-row>
173       <!-- 弹窗, 新增 / 修改 -->
174       <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate"
175                      @refreshDataList="getTableList('')"></add-or-update>
176     </div>
177   </el-card>
178 </template>
179
180 <script>
181   import AddOrUpdate from './document-add-or-update.vue'
182   import {Base64} from 'js-base64'
183   import {getHost, getFilePreviewUrl, reWriteUrl} from '@/utils/hostUtil'
184
185   export default {
186     data() {
187       return {
188         filterText: '',
189         data: [],
190         treeClickCount: 0,
191         showRightMenu: false,
192         formData: {},
193         targetElement: {},
194         dialogVisible: false,
195         addOrUpdateVisible: false,
196         form: {
197           labelName: ''
198         },
199         fileForm: {
200           keyWords: '',
201           title: '',
202           content: '',
203           treeId: ''
204         },
205         dataListLoading: false,
206         isRoot: false,
207         isLastNode: false,
208         isUpdate: false,
209         tableList: [],
210         pageIndex: 1,
211         pageSize: 10,
212         totalPage: 0,
213         chooseTreeId: '',
214         dataListSelections: [],
215         onlinePreviewUrl: '',
216         host: '',
217         tableLoading: false,
218         dataRule: {
219           labelName: [
220             {required: true, message: '不能为空', trigger: 'blur'}
221           ]
222         }
223       }
224     },
225     components: {
226       AddOrUpdate
227     },
228     activated() {
229       // this.getDataList()
230       this.setHost()
231     },
232     mounted() {
233       // this.getDataList()
234       this.setHost()
235     },
236     methods: {
237       // 获取数据列表
238       getDataList() {
239         this.dataListLoading = true
240         this.$http.get(`/iailab-ntt-model/knowledge/path/tree`).then(({data: res}) => {
241           this.dataListLoading = false
242           if (res.code !== 0) {
243             return this.$message.error(res.msg)
244           }
245           this.data = res.data
246           this.getTableList(this.chooseTreeId ? this.chooseTreeId : '')
247         }).catch(() => {
248         })
249       },
250       getTableList(treeId) {
251         this.chooseTreeId = treeId
252         this.tableLoading = true
253         this.$http.get(`/iailab-ntt-model/knowledge/det/page`,
254           {
255             params: {
256               'page': this.pageIndex,
257               'limit': this.pageSize,
258               'title': this.fileForm.title,
259               'keyWords': this.fileForm.keyWords,
260               'content': this.fileForm.content,
261               'treeId': treeId
262             }
263           }
264         ).then(({data: res}) => {
265           this.tableLoading = false
266           if (res && res.code === 0) {
267             this.tableList = res.data.list
268             this.totalPage = res.data.total
269           } else {
270             this.tableList = []
271             this.totalPage = 0
272           }
273         }).catch(() => {
274         })
275       },
276       // 树形图单击和双击事件
277       handleNodeClick(data, node) {
278         this.treeClickCount++
279         window.setTimeout(() => {
280           if (this.treeClickCount === 1) {
281             this.treeClickCount = 0
282             this.getTableList(data.id)
283           } else if (this.treeClickCount > 1) {
284             this.treeClickCount = 0
285             this.getTableList(data.id)
286             if (data.children.length > 0) {
287               node.expanded = !node.expanded
288             } else {
289               node.expanded = false
290             }
291           }
292         }, 300)
293       },
294       // 右键显示菜单
295       rightClick(event, data, node) {
296         if (data.id.indexOf('00') === -1) {
297           this.isLastNode = true
298         }
299         this.showRightMenu = false
300         this.showRightMenu = true
301         this.formData = data
302         this.targetElement = node
303         let menu = document.querySelector('#menu')
304         menu.style.left = `${event.clientX + 10}px`
305         menu.style.top = `${event.clientY}px`
306         document.addEventListener('click', this.closeRightMenu)
307       },
308       // 关闭右键菜单
309       closeRightMenu() {
310         this.showRightMenu = false
311         document.removeEventListener('click', this.closeRightMenu)
312       },
313       // 新增节点
314       addNode(isRoot) {
315         this.isRoot = isRoot
316         this.isUpdate = false
317         this.dialogVisible = true
318         this.$nextTick(() => {
319           this.$refs['form'].resetFields()
320         })
321       },
322       // 更改节点名称
323       updateNode() {
324         this.isUpdate = true
325         this.dialogVisible = true
326         this.form.labelName = this.formData.label
327       },
328       // 删除节点
329       deleteNode() {
330         this.$confirm(`确定对该节点进行删除操作?`, '提示', {
331           confirmButtonText: '确定',
332           cancelButtonText: '取消',
333           type: 'warning'
334         }).then(() => {
335           this.$http.delete(`/iailab-ntt-model/knowledge/path/${this.formData.id}`, this.dataForm).then(({data: res}) => {
336             if (res.code !== 0) {
337               return this.$message.error(res.msg)
338             }
339             this.$message({
340               message: this.$t('prompt.success'),
341               type: 'success',
342               duration: 500,
343               onClose: () => {
344                 this.visible = false
345                 this.getDataList()
346               }
347             })
348           }).catch(() => {
349           })
350         }).catch(() => {
351         })
352       },
353       // 新增或更改节点,表单提交
354       dataFormSubmit() {
355         this.$refs['form'].validate((valid) => {
356           if (!valid) {
357             return false
358           }
359           let id
360           let postData
361           this.dialogVisible = false
362           // 是否是更新节点
363           if (!this.isUpdate) {
364             // 是否新增的是根节点
365             if (this.isRoot) {
366               id = this.appendRoot()
367             } else {
368               id = this.append(this.formData)
369             }
370             postData = {id: id, label: this.form.labelName, parentId: this.isRoot ? '0000000000' : this.formData.id}
371           } else {
372             postData = {id: this.formData.id, label: this.form.labelName, parentId: this.formData.parentId}
373           }
374
375           this.$http[!this.isUpdate ? 'post' : 'put']('/iailab-ntt-model/knowledge/path', postData).then(({data: res}) => {
376             if (res.code !== 0) {
377               return this.$message.error(res.msg)
378             }
379             this.$message({
380               message: this.$t('prompt.success'),
381               type: 'success',
382               duration: 500,
383               onClose: () => {
384                 this.visible = false
385                 this.getDataList()
386               }
387             })
388           }).catch(() => {
389           })
390         })
391       },
392       // 新增根节点
393       appendRoot() {
394         let id
395         if (this.data.length > 0) {
396           let temp = (this.data[this.data.length - 1].id.substring(0, 2) * 1 + 1) + '00000000'
397           while (temp.length < 10) {
398             temp = '0' + temp
399           }
400           id = temp
401         } else {
402           id = '0100000000'
403         }
404         this.data.push({
405           id: id,
406           label: this.form.labelName,
407           children: []
408         })
409         return id
410       },
411       // 新增节点
412       append(data) {
413         let id = this.treeIdAdd(data)
414         const newChild = {id: id, label: this.form.labelName, children: []}
415         if (!data.children) {
416           this.$set(data, 'children', [])
417         }
418         data.children.push(newChild)
419         if (!this.targetElement.expanded) {
420           this.targetElement.expanded = true
421         }
422         return id
423       },
424       // 获取新增后的id
425       treeIdAdd(data) {
426         let index = data.id.indexOf('00')
427         let frontPart = data.id.substring(0, index)
428         let backPart = ''
429         if (index !== -1) {
430           if (data.children.length > 0) {
431             // 最大子节点id加1
432             let tempStr = '1'
433             for (let i = 0; i < (10 - index - 2); i++) {
434               tempStr = tempStr + '0'
435             }
436             backPart = (data.children[data.children.length - 1].id * 1 - data.id * 1 + tempStr * 1).toString()
437             while (backPart.length < 10 - index) {
438               backPart = '0' + backPart
439             }
440           } else {
441             // 在父节点id的基础上加一级
442             let tempStr = '01'
443             for (let i = 0; i < (10 - index - 2); i++) {
444               tempStr = tempStr + '0'
445             }
446             backPart = tempStr
447           }
448           return frontPart + backPart
449         }
450       },
451       // 新增 / 修改
452       addOrUpdateHandle(knowledgeId) {
453         this.addOrUpdateVisible = true
454         this.$nextTick(() => {
455           this.$refs.addOrUpdate.init(knowledgeId, this.chooseTreeId, this.data)
456         })
457       },
458       // 文件预览
459       filePreview(dataInfo) {
460         if (dataInfo.website) {
461           window.open(dataInfo.website)
462         } else {
463           window.open(this.onlinePreviewUrl + encodeURIComponent(Base64.encode(reWriteUrl(dataInfo.url))),
464             '_blank', 'width=1500,height=850,toolbar=no,scrollbars=no,menubar=no,screenX=240,screenY=100')
465         }
466       },
467       // 每页数
468       sizeChangeHandle(val) {
469         this.pageSize = val
470         this.pageIndex = 1
471         this.getDataList()
472       },
473       // 当前页
474       currentChangeHandle(val) {
475         this.pageIndex = val
476         this.getDataList()
477       },
478       onSuccess() {
479         this.$message({
480           message: '复制成功',
481           type: 'success',
482           duration: 1500
483         })
484       },
485       // 下载
486       download(url) {
487         window.open(reWriteUrl(url))
488       },
489       // 多选
490       selectionChangeHandle(val) {
491         this.dataListSelections = val
492       },
493       // 删除
494       deleteHandle(knowledgeId) {
495         const knowledgeIds = knowledgeId ? [knowledgeId] : this.dataListSelections.map(item => {
496           return item.id
497         })
498         this.$confirm(`确定对所选项目进行[${knowledgeId ? '删除' : '批量删除'}]操作?`, '提示', {
499           confirmButtonText: '确定',
500           cancelButtonText: '取消',
501           type: 'warning'
502         }).then(() => {
503           this.$http.delete('iailab-ntt-model/knowledge/det', {
504             data: knowledgeIds
505           }).then(({data}) => {
506             if (data && data.code === 0) {
507               this.$message({
508                 message: '操作成功',
509                 type: 'success',
510                 duration: 1500,
511                 onClose: () => {
512                   if (knowledgeIds.length === this.tableList.length) {
513                     this.pageIndex = 1
514                   }
515                   this.getDataList()
516                 }
517               })
518             } else {
519               this.$message.error(data.msg)
520             }
521           })
522         }).catch(() => {
523         })
524       },
525       // 处理鼠标事件
526       handleMouse(e) {
527         e.preventDefault()
528         return false
529       },
530       // 过滤节点
531       filterNode(value, data) {
532         if (!value) return true
533         return data.label.indexOf(value) !== -1
534       },
535       setHost() {
536         this.host = getHost()
537         this.onlinePreviewUrl = getFilePreviewUrl()
538       }
539     },
540     watch: {
541       filterText(val) {
542         this.$refs.tree.filter(val)
543       }
544     }
545   }
546 </script>
547
548 <style>
549   .dev-type-main-left {
550     overflow: auto;
551     padding: 10px;
552   }
553
554   .right-menu {
555     z-index: 999;
556     position: fixed;
557     height: auto;
558     border-radius: 5px;
559     border: 1px solid #ccc;
560     background-color: white;
561     padding: 15px;
562   }
563
564   .menu-item {
565     list-style-type: none;
566     line-height: 30px;
567     font-size: 15px;
568     color: #606266
569   }
570
571   li:hover {
572     background-color: #edf6ff;
573     color: #606266;
574   }
575
576   .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
577     background-color: rgba(135, 206, 235, 0.2);
578     color: #409eff;
579     font-weight: bold;
580   }
581 </style>