ai调用统计

This commit is contained in:
liuye
2024-01-17 14:13:00 +08:00
parent eaba5f7be7
commit 059112abba

View File

@@ -0,0 +1,471 @@
<template>
<section class="AppAiStatistics">
<ai-detail list>
<ai-title slot="title" title="AI调用统计">
<template #rightBtn>
<el-row type="flex" align="middle">
<!-- <el-cascader ref="cascader1" clearable v-model="totalDeptList" :options="deptOptions" placeholder="所属部门" size="small"
:props="defaultProps" :show-all-levels="false" @change="totalDeptSelect"></el-cascader> -->
<AiAreaGet style="width: 250px" clearable always-show :instance="instance" v-model="totalAreaId" placeholder="所属地区" @change="getTotal"></AiAreaGet>
</el-row>
</template>
</ai-title>
<template #content>
<div class="card_list">
<div class="card">
<h2>累计调用次数</h2>
<p class="color1">{{ totalInfo['累计'] || 0 }}</p>
</div>
<div class="card">
<h2>本月调用次数</h2>
<p class="color1">{{ totalInfo['本月'] || 0 }}</p>
</div>
<div class="card">
<h2>本周调用次数</h2>
<p class="color1">{{ totalInfo['本周'] || 0 }}</p>
</div>
<div class="card">
<h2>昨日调用次数</h2>
<p class="color1">{{ totalInfo['昨日'] || 0 }}</p>
</div>
</div>
<ai-title slot="title" :title="`AI调用分析(${totalEcount}次数)`">
<template #rightBtn>
<el-row type="flex" align="middle">
<span class="shortcut" v-for="(item,i) in timeCheck" :key="i" :class="{active:type==i}"
@click="timeChange(i)" v-text="item"/>
<!-- <el-cascader ref="cascader2" clearable v-model="deptList" :options="deptOptions" placeholder="所属部门" size="small"
:props="defaultProps" :show-all-levels="false" @change="deptSelect"></el-cascader> -->
<AiAreaGet style="width: 250px" clearable always-show :instance="instance" v-model="areaId" placeholder="所属地区" @change="getStatistics"></AiAreaGet>
</el-row>
</template>
</ai-title>
<el-row type="flex" class="mar-t4 gap-20">
<div class="chartBox fill">
<b>AI调用趋势图</b>
<div>
<div id="trendChart" style="height: 280px; width: 100%;" v-if="trendData.length"></div>
<ai-empty v-else style="height: 200px; width: 100%;" id="empty"/>
</div>
</div>
<div class="chartBox fill">
<b>AI调用群聊排行榜</b>
<div>
<ai-table v-if="tableData.length"
:tableData="tableData"
:col-configs="colConfigs"
:isShowPagination="false"
style="margin-top: 6px; width: 100%;">
</ai-table>
<ai-empty v-else style="height: 200px; width: 100%;" id="empty"/>
</div>
</div>
</el-row>
<ai-dialog :visible.sync="dialogDate" title="选择时间" width="500px" customFooter>
<el-date-picker v-model="timeList" size="small" type="daterange" value-format="yyyy-MM-dd"
range-separator="" start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
<el-button slot="footer" @click="selectDete" type="primary">确认</el-button>
</ai-dialog>
</template>
</ai-detail>
</section>
</template>
<script>
import {mapState} from "vuex"
import * as echarts from 'echarts';
import AiDetail from "dui/packages/layout/AiDetail.vue";
import AiTitle from "dui/packages/basic/AiTitle.vue";
import "echarts-wordcloud";
export default {
name: "AppAiStatistics",
components: {AiTitle, AiDetail},
label: "AI调用统计",
props: {
instance: Function,
dict: Object,
permissions: Function,
},
data() {
return {
defaultProps: {
label: 'name',
value: 'fullId',
checkStrictly: true,
},
deptOptions: [],
info: {},
trendData: [],
trendChart: null,
barData: [],
barChart: null,
wordData: [],
wordChart: null,
tableData: [],
totalInfo: {},
type: '0',
timeCheck: ['近7天', '近30天', '近1年', '自定义'],
dialog: false,
dialogDate: false,
timeList: [],
startTime: '',
endTime: '',
totalDeptList: [],
deptList: [],
time: [],
totalAreaId: '',
areaId: '',
totalEcount: 0
}
},
computed: {
...mapState(['user']),
colConfigs() {
return [
{prop: "rank", label: '排名', align: "center", width: "80px"},
{prop: "roomName", label: '群名称', align: "center"},
{prop: "ownerName", label: '群主', align: "center", width: "100px"},
{prop: "c", label: '触发数', align: "center", width: "100px"},
]
},
},
created() {
this.getDeptList()
this.getTotal()
this.getStatistics()
},
methods: {
getTotal() {
// var totalDepartmentId = this.totalDeptList.length ? this.totalDeptList[this.totalDeptList.length-1] : ''
this.instance.post(`/app/appmasssendingtaskbaidu/statistics1?areaId=${this.totalAreaId}`).then(res => {
if (res?.data) {
console.log(res)
this.totalInfo = res.data
}
})
},
getStatistics() {
this.trendData = [], this.barData = [], this.wordData = [], this.tableData = []
// var departmentId = this.deptList.length ? this.deptList[this.deptList.length-1] : ''
this.instance.post('/app/appmasssendingtaskbaidu/statistics2', null, {
params: {
// deptFullId: departmentId,
areaId: this.areaId,
type: this.type,
startTime: this.startTime,
endTime: this.endTime,
}
}).then(res => {
if (res?.data) {
this.info = res.data
var trendX = []
this.totalEcount = 0
this.info.trend.map((item) => {
trendX.push(item.ymd)
this.totalEcount = this.totalEcount + item.ecount
this.trendData.push(item.ecount)
})
if(this.trendData.length) {
this.$nextTick(() => {
this.trendChartInit(trendX, this.trendData)
})
}
// var barX = []
// this.info.typeList.map((item) => {
// barX.push(item.wordName)
// this.barData.push(item.c)
// })
// if(this.barData.length) {
// this.$nextTick(() => {
// this.barChartInit(barX, this.barData)
// })
// }
// this.info.wordNames.map((item) => {
// var i = { name: item.wordName, value: item.wordCount };
// this.wordData.push(i);
// })
// if(this.wordData.length) {
// this.$nextTick(() => {
// this.wordChartInit(this.wordData)
// })
// }
this.info.ranking.map((item, index)=> {
if(index < 5) {
item.rank = index+1
this.tableData.push(item)
}
})
}
})
},
trendChartInit(xData, yData) {
this.trendChart = echarts.init(document.getElementById('trendChart'))
let option = {
xAxis: {
type: 'category',
data: xData
},
yAxis: {
type: 'value'
},
grid: {
left: '10px',
right: '28px',
bottom: '14px',
top: '30px',
containLabel: true
},
tooltip: {
trigger: 'axis'
},
legend: {
type: "plain"
},
color: '#2891FF',
series: [
{
data: yData,
type: 'line'
}
]
}
this.trendChart.setOption(option)
},
barChartInit(xData, yData) {
this.barChart = echarts.init(document.getElementById('barChart'))
var option = {
color: ['#2891FF'],
grid: {
top: '10%',
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
},
xAxis: {
data: xData,
silent: false,
splitLine: {
show: false
},
splitArea: {
show: false
}
},
yAxis: {
splitArea: {
show: false
}
},
series: [
{
type: 'bar',
data: yData,
barWidth: 20,
barGap: '250%',
large: true
}
]
};
this.barChart.setOption(option)
},
wordChartInit(data) {
this.wordChart = echarts.init(document.getElementById('wordChart'))
var option = {
series: [
{
type: "wordCloud",
sizeRange: [15, 80],
rotationRange: [0, 0],
rotationStep: 45,
gridSize: 8,
shape: "pentagon",
width: "100%",
height: "100%",
textStyle: {
normal: {
color: function () {
return (
"rgb(" +
[
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
].join(",") +
")"
);
},
fontFamily: "sans-serif",
fontWeight: "normal",
},
emphasis: {
shadowBlur: 10,
shadowColor: "#333",
},
},
data,
},
],
}
this.wordChart.setOption(option)
},
getDeptList() {
this.instance.post(`/app/wxcp/wxdepartment/listAll`).then((res) => {
if (res.code == 0) {
this.deptOptions = this.toTree(res.data)
}
})
},
toTree(data) {
let result = [];
if (!Array.isArray(data)) {
return result
}
let map = {};
data.forEach(item => {
map[item.id] = item;
});
data.forEach(item => {
let parent = map[item.parentid];
if (parent) {
(parent.children || (parent.children = [])).push(item);
} else {
result.push(item);
}
});
return result;
},
totalDeptSelect() {
this.getTotal()
},
deptSelect() {
this.getStatistics()
},
timeChange(index) {
this.type = index
if (index == 3) {
this.dialogDate = true
} else {
this.startTime = ''
this.endTime = ''
this.getStatistics()
}
},
selectDete() {
if (!this.timeList || !this.timeList.length) {
return this.$message.error('请选择自定义时间');
}
this.startTime = this.timeList?.[0]
this.endTime = this.timeList?.[1]
this.dialogDate = false
this.getStatistics()
},
},
}
</script>
<style lang="scss" scoped>
.AppAiStatistics {
height: 100%;
box-sizing: border-box;
.shortcut {
display: inline-block;
width: 70px;
height: 32px;
line-height: 32px;
border-radius: 2px;
border: 1px solid #D0D4DC;
margin-right: 8px;
text-align: center;
cursor: pointer;
&.active {
color: #2266FF;
border: 1px solid #2266FF;
}
}
.chartBox {
background: #F9F9F9;
box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.1500);
border-radius: 4px;
padding: 16px;
box-sizing: border-box;
margin-top: 6px;
.chart {
width: 100%;
height: 300px;
}
}
.card_list {
display: flex;
margin-bottom: 4px;
.card {
flex: 1;
height: 76px;
background: #F9F9F9;
border-radius: 2px;
margin-right: 20px;
padding: 8px 24px;
box-sizing: border-box;
h2 {
color: #888888;
font-weight: 600;
font-size: 16px;
}
p {
margin-top: 8px;
font-size: 24px;
font-weight: 600;
}
.color1 {
color: #2891FF;
}
.color2 {
color: #22AA99;
}
.color3 {
color: #F8B425;
}
}
.card:last-child {
margin-right: 0;
}
}
:deep( .el-dialog__footer ) {
text-align: center;
}
:deep( .el-dialog__header ) {
border-bottom: 1px solid #DDD;
}
:deep( .ai-detail ) {
background: #FFF;
}
}
</style>