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