统计分析

This commit is contained in:
pan 2024-08-31 16:12:39 +08:00
parent bc6f4a50ea
commit 398b49b910
9 changed files with 267 additions and 121 deletions

View File

@ -1,45 +1,54 @@
import request from '@/utils/request' import request from '@/utils/request'
/** // 查询消息列表
* 查询消息列表 export function listMessage(query) {
* @returns return request({
*/ url: '/system/message/list',
export function getMessageList(params) { method: 'get',
return Promise.resolve({ params: query
total: 5,
rows: [
{ id: 1, msgContent: '测试1111', msgRecTime: '2024-08-05 12:31:59', msgStatus: 'unread' },
{ id: 2, msgContent: '测试2222', msgRecTime: '2024-08-05 13:32:01', msgStatus: 'readed' },
{ id: 3, msgContent: '测试333', msgRecTime: '2024-08-05 14:09:07', msgStatus: 'unread' },
{ id: 4, msgContent: '测试4444', msgRecTime: '2024-08-05 15:37:10', msgStatus: 'readed' },
{ id: 5, msgContent: '测试5555', msgRecTime: '2024-08-05 17:29:39', msgStatus: 'unread' }
],
code: 200,
msg: '操作成功'
}) })
} }
/** // 查询消息详细
* 标记所有已读 export function getMessage(id) {
* @returns return request({
*/ url: '/system/message/' + id,
export function markAllRead() { method: 'get'
return Promise.resolve({
result: {},
code: 200,
msg: '操作成功'
}) })
} }
/** // 新增消息
* 根据id标记单个已读 export function addMessage(data) {
* @returns return request({
*/ url: '/system/message',
export function markReadById(id) { method: 'post',
return Promise.resolve({ data: data
result: {},
code: 200,
msg: '操作成功'
}) })
} }
// 修改消息
export function updateMessage(data) {
return request({
url: '/system/message',
method: 'put',
data: data
})
}
// 删除消息
export function delMessage(id) {
return request({
url: '/system/message/' + id,
method: 'delete'
})
}
// 全部标记已读
export function allMarkedRead(data) {
return request({
url: '/system/message/allMarkedRead',
method: 'post',
data: data
})
}

View File

@ -0,0 +1,55 @@
import request from '@/utils/request'
// 查询工具下载统计列表
export function listCount(query) {
return request({
url: '/system/count/list',
method: 'get',
params: query
})
}
// 根据详情统计
export function userDownList(query) {
return request({
url: '/system/count/user/down/list',
method: 'get',
params: query
})
}
// 查询工具下载统计详细
export function getCount(id) {
return request({
url: '/system/count/' + id,
method: 'get'
})
}
// 新增工具下载统计
export function addCount(data) {
return request({
url: '/system/count',
method: 'post',
data: data
})
}
// 修改工具下载统计
export function updateCount(data) {
return request({
url: '/system/count',
method: 'put',
data: data
})
}
// 删除工具下载统计
export function delCount(id) {
return request({
url: '/system/count/' + id,
method: 'delete'
})
}

View File

@ -59,3 +59,13 @@ export function checkToolExist(params) {
params: params params: params
}) })
} }
// 获取统计信息
export function getStatistics(query) {
return request({
url: '/tool/statistics',
method: 'get',
params: query
})
}

View File

@ -4,15 +4,25 @@
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<div class="search"> <div class="search">
<div class="sl"> <div class="sl">
<el-form-item label="消息内容" prop="mesContent"> <el-form-item label="消息内容" prop="content">
<el-input <el-input
v-model="queryParams.mesContent" v-model="queryParams.content"
placeholder="请输入消息内容" placeholder="请输入消息内容"
clearable clearable
style="width: 240px" style="width: 240px"
@keyup.enter.native="handleQuery" @keyup.enter.native="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="states">
<el-select v-model="queryParams.states" placeholder="状态" clearable>
<el-option
v-for="dict in dict.type.msg_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</div> </div>
<div class="sr"> <div class="sr">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@ -22,40 +32,18 @@
</el-form> </el-form>
</el-card> </el-card>
<el-card class="lrtt"> <el-card class="lrtt">
<div class="lt">
<el-input
v-model="deptName"
placeholder="请输入部门名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
<div class="divide"></div><!--divide 分隔-->
<el-tree
:data="deptOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
/>
</div><!--lt -->
<div class="rt"> <div class="rt">
<div class="operate"> <div class="operate">
<el-button type="primary" @click="markRead(null)">全部标记已读</el-button> <el-button type="primary" @click="setAllMarkedRead">全部标记已读</el-button>
</div><!--operate 操作按钮--> </div><!--operate 操作按钮-->
<el-table v-loading="loading" :data="tableList"> <el-table v-loading="loading" :data="tableList">
<el-table-column label="消息内容" prop="msgContent" min-width="120" /> <el-table-column label="消息内容" prop="content" min-width="120" />
<el-table-column label="接收时间" prop="msgRecTime" :show-overflow-tooltip="true" min-width="120"/> <el-table-column label="接收时间" prop="createTime" :show-overflow-tooltip="true" min-width="120"/>
<el-table-column label="消息状态" prop="msgStatus" :show-overflow-tooltip="true" min-width="80" > <el-table-column label="消息状态" prop="states" :show-overflow-tooltip="true" min-width="80" >
<template v-slot="{ row }"> <template v-slot="{ row }">
<template v-for="dict in dict.type.msg_status"> <template v-for="dict in dict.type.msg_status">
<!-- {{ dict }} --> <!-- {{ dict }} -->
<el-tag :type="dict.raw.listClass" v-if="row.msgStatus == dict.value" :key="dict.value">{{ dict.label }}</el-tag> <el-tag :type="dict.raw.listClass" v-if="row.states == dict.value" :key="dict.value">{{ dict.label }}</el-tag>
</template> </template>
</template> </template>
</el-table-column> </el-table-column>
@ -64,8 +52,8 @@
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
v-if="row.msgStatus === 'unread'" v-if="row.states == '1'"
@click="markRead(row.id)" @click="markRead(row)"
>标记已读</el-button> >标记已读</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -83,7 +71,7 @@
</template> </template>
<script> <script>
import { markAllRead, markReadById, getMessageList } from "@/api/message/message" import { listMessage, getMessage, delMessage, addMessage, updateMessage,allMarkedRead } from "@/api/message/message"
import { deptTreeSelect } from "@/api/system/user"; import { deptTreeSelect } from "@/api/system/user";
export default { export default {
@ -128,7 +116,8 @@ export default {
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
mesContent: '' content: '',
states: '',
}, },
}; };
}, },
@ -145,7 +134,8 @@ export default {
}, },
getList() { getList() {
this.loading = true this.loading = true
getMessageList(this.queryParams).then(response => { this.$set(this.queryParams,"createById", this.$store.getters.userId)
listMessage(this.queryParams).then(response => {
this.total = response?.total this.total = response?.total
this.tableList = response?.rows || [] this.tableList = response?.rows || []
this.loading = false this.loading = false
@ -176,24 +166,41 @@ export default {
* 标记已读id为null时表示标记全部已读 * 标记已读id为null时表示标记全部已读
* @param id * @param id
*/ */
markRead(id) { markRead(row) {
this.$confirm('确认标记已读吗?', '提示', { let self = this
self.$confirm('确认标记已读吗?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
if(id) { let formData = JSON.parse(JSON.stringify(row))
markReadById(id).then(response => { self.$set(formData, "states", 2)
this.$modal.msgSuccess(response?.msg || '操作成功') updateMessage(formData).then(response => {
this.getList(); self.$modal.msgSuccess(response?.msg || '操作成功')
}) self.getList();
} else {
markAllRead().then(response => {
this.$modal.msgSuccess(response?.msg || '操作成功')
this.getList();
}) })
}).catch((err) => {console.error(err)});
},
/**
* 标记已读id为null时表示标记全部已读
* @param id
*/
setAllMarkedRead() {
let self = this
self.$confirm('确认全部标记已读吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let formData = {
"states": 2
} }
}).catch(() => {}); allMarkedRead(formData).then(response => {
self.$modal.msgSuccess(response?.msg || '操作成功')
self.getList();
})
}).catch((err) => {console.error(err)});
}, },
} }
}; };

View File

@ -85,7 +85,7 @@ export default {
}, },
series: [ series: [
{ {
name: 'WEEKLY WRITE ARTICLES', name: '',
type: 'pie', type: 'pie',
roseType: this.roseType, roseType: this.roseType,
radius: this.radius, radius: this.radius,

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="app-container"> <div class="app-container" v-loading="pageloading">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-card> <el-card>
<div slot="header" class="clearfix"><span class="tline">工具类别统计</span></div> <div slot="header" class="clearfix"><span class="tline">工具类别统计</span></div>
<!-- --> <!-- -->
<div class="tjbox2"> <div class="tjbox2" v-if="isPieChart">
<PieChart <PieChart
height="207px" height="207px"
:data="toolTypeData" :data="toolTypeData"
@ -20,7 +20,7 @@
<el-col :span="12"> <el-col :span="12">
<el-card> <el-card>
<div slot="header" class="clearfix"><span class="tline">工具状态统计</span></div> <div slot="header" class="clearfix"><span class="tline">工具状态统计</span></div>
<div class="tjbox2"> <div class="tjbox2" v-if="isPieChart">
<PieChart <PieChart
height="207px" height="207px"
:data="toolStatusData" :data="toolStatusData"
@ -39,7 +39,7 @@
<el-col :span="12"> <el-col :span="12">
<el-card> <el-card>
<div slot="header" class="clearfix"><span class="tline">工具来源统计</span></div> <div slot="header" class="clearfix"><span class="tline">工具来源统计</span></div>
<div class="tjbox2"> <div class="tjbox2" v-if="isPieChart">
<PieChart <PieChart
height="207px" height="207px"
:data="toolSourceData" :data="toolSourceData"
@ -133,11 +133,15 @@
</template> </template>
<script> <script>
import { getStatistics } from "@/api/tool/tool";
import { listCount,userDownList } from "@/api/tool/downloadCount";
import PieChart from './PieChart' import PieChart from './PieChart'
import DownStatDetail from './DownStatDetail' import DownStatDetail from './DownStatDetail'
import { getToolDownStat, getToolDownDetailStatistics } from '@/api/statistic/statistic' import { getToolDownStat, getToolDownDetailStatistics } from '@/api/statistic/statistic'
export default { export default {
name: 'statistic', name: 'statistic',
dicts: ['tool_type', 'flow_status', 'tool_source'],
components: { components: {
PieChart, PieChart,
DownStatDetail DownStatDetail
@ -147,24 +151,27 @@ export default {
toolDownDetailStatList: [], toolDownDetailStatList: [],
activeName: 'first', activeName: 'first',
toolTypeData: [ toolTypeData: [
{ value: 320, name: '检测型' }, /*{ value: 320, name: '' },
{ value: 240, name: '服务型' } { value: 240, name: '服务型' }*/
], ],
toolTypeLegendData:['检测型', '服务型'], // toolTypeLegendData:['', ''],
toolTypeLegendData:[],
toolStatusData: [ toolStatusData: [
{ value: 212, name: '已保存' }, /* { value: 212, name: '' },
{ value: 76, name: '审批中' }, { value: 76, name: '审批中' },
{ value: 32, name: '审批不通过' }, { value: 32, name: '审批不通过' },
{ value: 971, name: '已发布' } { value: 971, name: '已发布' }*/
], ],
toolStatusLegendData: ['已保存','审批中','审批不通过','已发布'], // toolStatusLegendData: ['','','',''],
toolStatusLegendData: [],
toolSourceData: [ toolSourceData: [
{ value: 20, name: 'QQ' }, /*{ value: 20, name: 'QQ' },
{ value: 60, name: '微信' }, { value: 60, name: '微信' },
{ value: 18, name: '官网' }, { value: 18, name: '官网' },
{ value: 47, name: '熟人介绍' } { value: 47, name: '熟人介绍' }*/
], ],
toolSourceLegendData: ['QQ', '微信', '官网', '熟人介绍'], // toolSourceLegendData: ['QQ', '', '', ''],
toolSourceLegendData: [],
// //
dateRange: [], dateRange: [],
toolDownStatList: [], toolDownStatList: [],
@ -174,12 +181,11 @@ export default {
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
mesContent: ''
}, },
queryParams1: { queryParams1: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
mesContent: '' toolId: ''
}, },
// //
detailDrawerOpen: false, detailDrawerOpen: false,
@ -188,10 +194,12 @@ export default {
// //
toolName: '', toolName: '',
total: 0, total: 0,
loading: false loading: false,
isPieChart: false,
} }
}, },
created () { created () {
this.getCountData()
this.getToolDownStatistics() this.getToolDownStatistics()
}, },
methods: { methods: {
@ -199,16 +207,19 @@ export default {
this.getToolDownDetailStatistics() this.getToolDownDetailStatistics()
}, },
getToolDownDetailStatistics() { getToolDownDetailStatistics() {
let self = this
this.loading = true this.loading = true
getToolDownDetailStatistics({ ...this.detailQueryParams, toolId: this.toolId }).then(response => { userDownList(this.addDateRange(this.queryParams1)).then(res => {
this.total = response?.total console.info("res=========", res)
this.toolDownDetailStatList = response?.rows || [] self.total = res?.total
this.loading = false self.toolDownDetailStatList = res?.rows || []
}).catch(() => { this.loading = false }); self.loading = false
}).catch(() => { self.loading = false });
}, },
// //
reset() { reset() {
this.toolDownStatList = [] this.toolDownStatList = []
this.dateRange = []
this.resetForm("queryForm") this.resetForm("queryForm")
this.handleQuery() this.handleQuery()
}, },
@ -223,18 +234,65 @@ export default {
* 获取工具下载列表数据 * 获取工具下载列表数据
*/ */
getToolDownStatistics() { getToolDownStatistics() {
let self = this
this.downLoading = true this.downLoading = true
getToolDownStat(this.queryParams).then(response => { listCount(this.addDateRange(this.queryParams, this.dateRange)).then(res => {
this.downTotal = response?.total console.info("res=========", res)
this.toolDownStatList = response?.rows || [] self.total = res?.total
this.downLoading = false self.toolDownStatList = res?.rows || []
}).catch(() => { this.downLoading = false }); self.downLoading = false
}).catch(() => { self.downLoading = false });
}, },
handleDetail(row){ handleDetail(row){
this.toolId = row.id this.$set(this.queryParams1, "toolId", row.toolId)
this.toolName = row.toolName
this.detailDrawerOpen = true this.detailDrawerOpen = true
}, },
/** 统计类型、类别、状态**/
getCountData(){
let self = this
self.toolTypeData = []
self.toolTypeLegendData = []
self.toolStatusData = []
self.toolStatusLegendData = []
self.toolSourceData = []
self.toolSourceLegendData = []
self.pageloading = true
getStatistics(this.queryParams).then(res => {
console.info("res===========", res)
if(res.data){
//
self.toolTypeData = JSON.parse(JSON.stringify(res.data.countToolType))
self.toolTypeData.forEach(item => {
self.toolTypeLegendData.push(item.name)
})
//
self.toolStatusData = JSON.parse(JSON.stringify(res.data.recordStatus))
self.toolStatusData.forEach(item => {
self.toolStatusLegendData.push(item.name)
})
//
self.toolSourceData = JSON.parse(JSON.stringify(res.data.toolSource))
self.toolSourceData.forEach(item => {
self.toolSourceLegendData.push(item.name)
})
self.isPieChart= true
self.pageloading= false
}
/* console.info("countToolType==============", this.dict.type.tool_type)
console.info("res===========", res)*/
}).catch((err) => {
self.isPieChart= true
self.pageloading= false
console.error(err)
});
}
} }
} }
</script> </script>

View File

@ -104,7 +104,7 @@
<el-table-column label="负责人" align="center" key="toolPrincipalsName" prop="toolPrincipalsName" v-if="columns[4].visible" width="120" /> <el-table-column label="负责人" align="center" key="toolPrincipalsName" prop="toolPrincipalsName" v-if="columns[4].visible" width="120" />
<el-table-column label="状态" align="center" key="status" v-if="columns[5].visible"> <el-table-column label="状态" align="center" key="status" v-if="columns[5].visible">
<template slot-scope="scope"> <template slot-scope="scope">
<dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> <dict-tag :options="dict.type.tool_status" :value="scope.row.status"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160"> <el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
@ -215,7 +215,7 @@ import mainComponent from "@/components/mainComponent/index.vue";
export default { export default {
name: "User", name: "User",
dicts: ['sys_normal_disable', 'tool_type'], dicts: ['sys_normal_disable', 'tool_type', 'tool_status'],
components: { Treeselect, toolDetail, AddDoc,mainComponent }, components: { Treeselect, toolDetail, AddDoc,mainComponent },
data() { data() {
return { return {

View File

@ -8,10 +8,10 @@
<el-row> <el-row>
<el-col :span="12"> <el-form-item label="工具名称">{{toolDetail.toolName}}</el-form-item> </el-col> <el-col :span="12"> <el-form-item label="工具名称">{{toolDetail.toolName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具类别"><dict-tag :options="dict.type.tool_type" :value="toolDetail.toolType"/></el-form-item> </el-col> <el-col :span="12"> <el-form-item label="工具类别"><dict-tag :options="dict.type.tool_type" :value="toolDetail.toolType"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具来源">{{toolDetail.toolSource}}</el-form-item> </el-col> <el-col :span="12"> <el-form-item label="工具来源"><dict-tag :options="dict.type.tool_source" :value="toolDetail.toolSource"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="负责人">{{toolDetail.toolPrincipalsName}}</el-form-item> </el-col> <el-col :span="12"> <el-form-item label="负责人">{{toolDetail.toolPrincipalsName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="归属单位">{{toolDetail.toolRespDeptName}}</el-form-item> </el-col> <el-col :span="12"> <el-form-item label="归属单位">{{toolDetail.toolRespDeptName}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="状态"><dict-tag :options="dict.type.sys_normal_disable" :value="toolDetail.status"/></el-form-item> </el-col> <el-col :span="12"> <el-form-item label="状态"><dict-tag :options="dict.type.tool_status" :value="toolDetail.status"/></el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="工具用途">{{toolDetail.toolUse}}</el-form-item> </el-col> <el-col :span="12"> <el-form-item label="工具用途">{{toolDetail.toolUse}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="测评情况">{{toolDetail.testSituation}}</el-form-item> </el-col> <el-col :span="12"> <el-form-item label="测评情况">{{toolDetail.testSituation}}</el-form-item> </el-col>
<el-col :span="12"> <el-form-item label="功能描述">{{toolDetail.functionDesc}}</el-form-item> </el-col> <el-col :span="12"> <el-form-item label="功能描述">{{toolDetail.functionDesc}}</el-form-item> </el-col>
@ -47,8 +47,8 @@
<span>{{ parseTime(scope.row.createTime) }}</span> <span>{{ parseTime(scope.row.createTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="180"> <el-table-column label="操作" align="center" width="180" v-if="toolDetail.downloadStatus">
<template slot-scope="scope" v-if="scope.row.roleId !== 1"> <template slot-scope="scope">
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -136,7 +136,7 @@
export default { export default {
name: 'toolDetail', name: 'toolDetail',
components: { editDocument, AddDoc, iFrame }, components: { editDocument, AddDoc, iFrame },
dicts:['sys_normal_disable','tool_type','doc_class','doc_source'], dicts:['sys_normal_disable','tool_type','tool_source','tool_status','doc_class','doc_source'],
props: { props: {
toolDetail: { toolDetail: {
type: Object, type: Object,

View File

@ -55,8 +55,15 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="工具来源" prop="toolSource"> <el-form-item label="工具来源" prop="toolSource">
<el-input v-if="editStatus" v-model="form.toolSource" placeholder="请输入工具来源"/> <el-select v-if="editStatus" v-model="form.toolSource" placeholder="请选择工具来源" style="width: 100%">
<span v-else>{{form.toolSource}}</span> <el-option
v-for="dict in dict.type.tool_source"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
<dict-tag v-else :options="dict.type.tool_source" :value="form.toolSource"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -84,12 +91,12 @@
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status" v-if="editStatus"> <el-radio-group v-model="form.status" v-if="editStatus">
<el-radio <el-radio
v-for="dict in dict.type.sys_normal_disable" v-for="dict in dict.type.tool_status"
:key="dict.value" :key="dict.value"
:label="dict.value" :label="dict.value"
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
<dict-tag v-else :options="dict.type.sys_normal_disable" :value="form.status"/> <dict-tag v-else :options="dict.type.tool_status" :value="form.status"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -301,7 +308,7 @@ import ToolSelector from '@/components/tool-selector/index.vue'
import { Base64 } from 'js-base64' import { Base64 } from 'js-base64'
// PDF // PDF
export default { export default {
dicts: ['sys_normal_disable','tool_type','doc_source','doc_class'], dicts: ['sys_normal_disable','tool_type', 'tool_source', 'tool_status', 'doc_source','doc_class'],
components: { components: {
ToolSelector, ToolSelector,
blUserSelector, blUserSelector,