357 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			357 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <script>
 | |
| import AiDrag from "./AiDrag.vue";
 | |
| import {Loading} from "element-ui";
 | |
| import AiDvSvg from "./layout/AiDvSvg/AiDvSvg.vue";
 | |
| import AiEchart from "dui/packages/tools/AiEchart.vue";
 | |
| 
 | |
| export default {
 | |
|   name: "AiAssist",
 | |
|   components: {AiEchart, AiDvSvg, AiDrag},
 | |
|   data() {
 | |
|     return {
 | |
|       dialog: false,
 | |
|       prompt: "",
 | |
|       content: "",
 | |
|       assistPos: {},
 | |
|       reply: {
 | |
|         table: [
 | |
|           {address: "张家堡街道", count: 132, handle: 132},
 | |
|           {address: "徐家湾街道", count: 125, handle: 225},
 | |
|           {address: "未央湖街道", count: 157, handle: 572},
 | |
|           {address: "辛家庙街道", count: 142, handle: 422},
 | |
|           {address: "六村堡街道", count: 233, handle: 453},
 | |
|         ],
 | |
|         chart: {
 | |
|           ops: {
 | |
|             tooltip: {
 | |
|               trigger: 'axis',
 | |
|               axisPointer: {
 | |
|                 type: 'shadow'
 | |
|               }
 | |
|             },
 | |
|             color: '#00EFFF',
 | |
|             yAxis: {
 | |
|               type: 'category',
 | |
|               axisLine: {
 | |
|                 show: true,
 | |
|                 lineStyle: {
 | |
|                   color: 'rgba(179, 223, 255, 0.5)',
 | |
|                   width: 1
 | |
|                 }
 | |
|               },
 | |
|               axisLabel: {
 | |
|                 color: '#8FABBF',
 | |
|               },
 | |
|               axisTick: {
 | |
|                 alignWithLabel: true,
 | |
|                 show: false
 | |
|               },
 | |
|               data: ['贷款', '诈骗', '失火', '消防', '醉酒']
 | |
|             },
 | |
|             xAxis: {
 | |
|               type: 'value',
 | |
|               axisLabel: {
 | |
|                 color: '#8FABBF',
 | |
|                 interval: 0
 | |
|               },
 | |
|               splitLine: {
 | |
|                 show: true,
 | |
|                 lineStyle: {
 | |
|                   color: 'rgba(61, 82, 102, 0.65)',
 | |
|                   width: 1,
 | |
|                   type: 'dashed'
 | |
|                 }
 | |
|               }
 | |
|             },
 | |
|             grid: {
 | |
|               left: '4%',
 | |
|               right: '1%',
 | |
|               bottom:0,
 | |
|               top: 0,
 | |
|               containLabel: true
 | |
|             },
 | |
|             series: [
 | |
|               {
 | |
|                 data: [919, 1210, 9794, 3559, 743],
 | |
|                 type: 'bar',
 | |
|                 barWidth: '25%',
 | |
|                 itemStyle: {
 | |
|                   color: {
 | |
|                     type: 'linear', x: 1, y: 0, x2: 0, y2: 0, colorStops: [
 | |
|                       {offset: 0, color: '#02FEFF'},
 | |
|                       {offset: 1, color: '#00527d1c'}
 | |
|                     ]
 | |
|                   }
 | |
|                 },
 | |
|                 backgroundStyle: {
 | |
|                   color: '#00527d1c'
 | |
|                 }
 | |
|               }
 | |
|             ]
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     isAiResult: v => v.content == "您好!一下是这个月敏感词触发情况概览:"
 | |
|   },
 | |
|   methods: {
 | |
|     confirm() {
 | |
|       const loading = Loading.service({fullscreen: true, text: "助手回复中...", background: "rgba(0, 0, 0, 0.2)"});
 | |
|       if (/(网格建设|居民报事|居民档案|两委干部|敏感词)/.test(this.prompt)) {
 | |
|         setTimeout(() => {
 | |
|           loading.close()
 | |
|           this.content = "您好!一下是这个月敏感词触发情况概览:"
 | |
|         }, 3000)
 | |
|       } else {
 | |
|         this.content = "抱歉,我还没有学习到关于这个话题的内容,无法提供相关信息。您可以选择其他问题,我将努力为您解答。"
 | |
|         loading.close()
 | |
|         // this.dialog = false
 | |
|       }
 | |
|       this.prompt = ""
 | |
|     },
 | |
|   },
 | |
|   watch: {
 | |
|     dialog(v) {
 | |
|       document.body.onclick = v ? () => this.dialog = false : null
 | |
|       if (!v) {
 | |
|         this.content = ""
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   mounted() {
 | |
|     const {x, y} = this.$el.getBoundingClientRect()
 | |
|     this.assistPos = {left: `calc(50vw - ${x}px)`, top: `calc(50vh - ${y}px)`}
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <template>
 | |
|   <section class="AiAssist" @click.stop>
 | |
|     <div class="pointer" @click="dialog=true">
 | |
|       <img src="https://cdn.cunwuyun.cn/dvcp/dv/aiIcon.png"/>
 | |
|       <div class="avatar-text" v-text="'全局AI助手'"/>
 | |
|     </div>
 | |
|     <ai-drag class="assistDialog" v-if="dialog" :resizable="false">
 | |
|       <div class="inbox" :style="assistPos">
 | |
|         <dv-border-box-1 v-if="!content" background-color="#001C30">
 | |
|           <div class="title mar-b32 mar-t16">慧智会言</div>
 | |
|           <el-input v-model="prompt" placeholder="您说,我在听~" clearable size="small">
 | |
|             <template #append><i class="el-icon-microphone">语音输入</i></template>
 | |
|           </el-input>
 | |
|           <div class="flex center gap-8 mar-t56">
 | |
|             <div class="btn" @click="dialog=false">取消</div>
 | |
|             <div class="btn" @click="confirm">确定</div>
 | |
|           </div>
 | |
|         </dv-border-box-1>
 | |
|         <ai-dv-svg v-else class="reply" @close="dialog=false">
 | |
|           <div class="w100" v-html="content"/>
 | |
|           <template v-if="isAiResult">
 | |
|             <div class="glass flex mar-v8">
 | |
|               <div class="sta fill">网格员总人数<span>5118</span>
 | |
|                 <p>人</p></div>
 | |
|               <div class="sta">网格划分<span>3118</span>
 | |
|                 <p>个</p></div>
 | |
|             </div>
 | |
|             <h2>敏感词处理情况</h2>
 | |
|             <el-table size="mini" :data="reply.table" stripe class="w100 mar-v8">
 | |
|               <el-table-column prop="address" label="地方"/>
 | |
|               <el-table-column prop="count" label="触发次数" width="100" align="right"/>
 | |
|               <el-table-column prop="handle" label="已处理" width="100" align="right"/>
 | |
|             </el-table>
 | |
|             <h2>敏感词触发统计</h2>
 | |
|             <ai-echart v-bind="reply.chart" class="mar-v8" id="KeywordChart"/>
 | |
|             <div class="flex column mar-b16">
 | |
|               <div class="btn">导出到本地</div>
 | |
|             </div>
 | |
|           </template>
 | |
|         </ai-dv-svg>
 | |
|       </div>
 | |
|     </ai-drag>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <style scoped lang="scss">
 | |
| $theme-color: #23ECFD;
 | |
| .AiAssist {
 | |
|   color: white;
 | |
|   font-size: 14px;
 | |
| 
 | |
|   .avatar-text {
 | |
|     text-align: center;
 | |
|     color: white;
 | |
|   }
 | |
| 
 | |
|   :deep(.assistDialog) {
 | |
|     .border-box-content {
 | |
|       padding: 16px 28px;
 | |
|       position: relative;
 | |
|       $gap-v: 6px;
 | |
|       $gap-h: 8px;
 | |
| 
 | |
|       &:after {
 | |
|         position: absolute;
 | |
|         left: $gap-h;
 | |
|         right: $gap-h;
 | |
|         top: $gap-v;
 | |
|         bottom: $gap-v;
 | |
|         content: " ";
 | |
|         box-shadow: 4px 4px 10px $theme-color inset, -4px -4px 10px $theme-color inset;
 | |
|         $v: 14px;
 | |
|         $vv: calc(100% - #{$v});
 | |
|         clip-path: polygon($v 0, $vv 0, 100% $v, 100% $vv, $vv 100%, $v 100%, 0 $vv, 0 $v);
 | |
|         pointer-events: none;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .inbox {
 | |
|       width: 400px;
 | |
|       height: 230px;
 | |
|       position: fixed;
 | |
|       transform: translate(-50%, -50%);
 | |
| 
 | |
|       .title {
 | |
|         text-align: center;
 | |
|         font-size: 14px;
 | |
|         background-image: url("https://cdn.cunwuyun.cn/dvcp/dv/weiyang/titleBg.png");
 | |
|         background-repeat: no-repeat;
 | |
|         background-position: center bottom;
 | |
|       }
 | |
| 
 | |
|       .el-input {
 | |
|         input {
 | |
|           background: transparent;
 | |
|           border-color: $theme-color;
 | |
|           color: white;
 | |
| 
 | |
|           &::placeholder {
 | |
|             color: #B3DAE5;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         .el-input-group__append {
 | |
|           user-select: none;
 | |
|           color: white;
 | |
|           background: $theme-color;
 | |
|           border-color: $theme-color;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .reply {
 | |
|       font-size: 14px;
 | |
| 
 | |
|       .glass {
 | |
|         width: 100%;
 | |
|         padding: 18px 14px;
 | |
|         background: hsla(0, 0%, 100%, .04);
 | |
|       }
 | |
| 
 | |
|       .sta {
 | |
|         display: flex;
 | |
|         align-items: baseline;
 | |
|         gap: 4px;
 | |
|         font-size: 12px;
 | |
| 
 | |
|         span {
 | |
|           font-family: D-DIN;
 | |
|           font-size: 18px;
 | |
|           color: $theme-color;
 | |
|         }
 | |
| 
 | |
|         p {
 | |
|           color: $theme-color;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       h2 {
 | |
|         font-size: 14px;
 | |
|         height: 30px;
 | |
|         line-height: 30px;
 | |
|         padding: 0px 10px;
 | |
|         background-image: linear-gradient(270deg, rgba(31, 67, 102, 0), rgba(31, 78, 102, 0.4));
 | |
|       }
 | |
| 
 | |
|       .el-table {
 | |
|         font-size: 13px;
 | |
|         color: #fff;
 | |
|         background-color: transparent !important;
 | |
| 
 | |
|         .el-table__header {
 | |
|           background: rgba(33, 180, 253, 0.1);
 | |
|         }
 | |
| 
 | |
|         &::before {
 | |
|           display: none !important;
 | |
|         }
 | |
| 
 | |
|         tr.el-table__row--striped td {
 | |
|           background: rgba(33, 180, 253, 0.1) !important;
 | |
|         }
 | |
| 
 | |
|         .el-table th.el-table__cell {
 | |
|           background: transparent !important;
 | |
|         }
 | |
| 
 | |
|         .el-table__header tr th:first-child .cell {
 | |
|           padding-left: 20px !important;
 | |
|         }
 | |
| 
 | |
|         .el-table__header tr th.is-right .cell {
 | |
|           padding-right: 20px !important;
 | |
|         }
 | |
| 
 | |
|         .el-table__body tr td.is-right .cell {
 | |
|           padding-right: 20px !important;
 | |
|         }
 | |
| 
 | |
|         .el-table__body tr td:first-child .cell {
 | |
|           padding-left: 20px !important;
 | |
|         }
 | |
| 
 | |
|         &.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
 | |
|           background-color: rgba(33, 180, 253, 0.1) !important;
 | |
|         }
 | |
| 
 | |
|         td.el-table__cell, th.el-table__cell.is-leaf {
 | |
|           border-bottom: none !important;
 | |
|         }
 | |
| 
 | |
|         th.el-table__cell {
 | |
|           background-color: transparent !important;
 | |
|         }
 | |
| 
 | |
|         tr {
 | |
|           background-color: transparent !important;
 | |
|         }
 | |
| 
 | |
|         .el-table__cell {
 | |
|           padding: 7px 0;
 | |
|           color: #d0e1e8;
 | |
|         }
 | |
| 
 | |
|         .el-table__header tr .cell {
 | |
|           color: #02FEFF !important;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       #KeywordChart {
 | |
|         width: 100%;
 | |
|         height: 180px;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .btn {
 | |
|     background-image: linear-gradient(180deg, #5ac8f666 0%, #01336566 84%);
 | |
|     box-shadow: inset 0 2px 8px 0 #33bbff80;
 | |
|     border-radius: 4px;
 | |
|     line-height: 30px;
 | |
|     text-align: center;
 | |
|     cursor: pointer;
 | |
|     padding: 0 16px;
 | |
|   }
 | |
| }
 | |
| </style>
 |