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