Browse Source

信访大屏前端2.0

main
parent
commit
b408af7843
  1. 18
      src/api/data/basicScreen.ts
  2. 21
      src/api/data/supervisionNotify.ts
  3. 194
      src/components/datav/chart-bar-new.vue
  4. 8
      src/components/datav/statistic.vue
  5. 10
      src/views/data/Ajhc.vue
  6. 32
      src/views/data/Mail12337.vue
  7. 204
      src/views/datav/Gobal.vue
  8. 124
      src/views/datav/SceneInsp.vue

18
src/api/data/basicScreen.ts

@ -0,0 +1,18 @@
import request from "@/api/request";
/**
* api
* @author: sh
* @date: 2024-011-7
*/
export function getAllGobalCount(times) {
return request.get({
url: `/datav/dataGobalScreen?beginTime=${times[0]}&endTime=${times[1]}`
});
}

21
src/api/data/supervisionNotify.ts

@ -0,0 +1,21 @@
import request from "@/api/request";
export function importCaseVerif(body) {
return request.post({
url: '/data/caseVerif/import',
body
});
}
export function listCaseVerif(query) {
return request.get({
url: '/data/caseVerif',
query
});
}
export function getAllSupervisionNotifyCount(times) {
return request.get({
url: `/datav/supervisonNotify?beginTime=${times[0]}&endTime=${times[1]}`
});
}

194
src/components/datav/chart-bar-new.vue

@ -0,0 +1,194 @@
<template>
<!-- 顶部标题和子标题 -->
<div class="flex between v-center mb-10">
<span class="bar-title">{{ title }}</span>
<span class="bar-sub-title">{{ subTitle }}</span>
</div>
<!-- 条目列表 -->
<div>
<div
class="flex v-center bar-item between wrap"
v-for="item in data"
:size="size"
:style="{ '--label-width': `${labelWidth}px` }"
:position="labelPosition"
>
<!-- 条目标签 -->
<span class="bar-item-label mr-10">
{{ item.label }}
</span>
<!-- 条目内容 -->
<div class="bar-item_content mr-16">
<div
class="bar-item_content-bar"
:style="{
width: `${(item.value / max) * 100}%`,
background: getColor((item.value / max) * 100),
}"
></div>
</div>
<!-- 条目值 -->
<span class="mr-16">{{ item.value }}</span>
<!-- 条目备注 -->
<span
class="bar-item_remark text-right"
v-if="item.denominator"
style="min-width: 40px"
>
<span class="text-success">{{ item.numerator }}</span>
<span>/</span>
<span>{{ item.denominator }}</span>
</span>
</div>
</div>
</template>
<script setup>
import {onMounted, ref, watch} from "vue";
const props = defineProps({
title: {
type: String,
default: "",
},
subTitle: {
type: String,
default: "",
},
data: {
type: Array,
default: [],
},
size: {
type: String,
default: "",
},
unit: {
type: String,
default: "",
},
color: {
type: [Object, String],
default: "linear-gradient(270deg, #63e700 0%, #19674c 100%)",
},
labelWidth: {
type: Number,
default: 80,
},
labelPosition: {
type: String,
default: "left",
},
});
const max = ref(100);
// data max
watch(
() => props.data,
() => {
getMax();
}
);
//
function getMax() {
if (props.unit !== "%") {
max.value = Math.max(...props.data.map((item) => item.value));
}
}
//
onMounted(() => {
getMax();
});
//
function getColor(val) {
if (typeof props.color === "string") {
return props.color;
}
if (Array.isArray(props.color)) {
const colors = [...props.color];
colors.sort((a, b) => b.percentage - a.percentage);
for (let i = 0; i < colors.length; i++) {
if (val > colors[0].percentage) {
return colors[0].color;
}
}
}
return "linear-gradient(270deg, #63e700 0%, #19674c 100%)";
}
</script>
<style lang="scss" scoped>
.bar-title {
font-size: 19px;
}
.bar-sub-title {
color: #597ae9;
font-size: 14px;
}
.bar-item {
font-size: 17px;
&[size="large"] {
.bar-item_content {
.bar-item_content-bar {
height: 13px;
}
}
}
&[size="small"] {
font-size: 12px;
}
.bar-item-label {
text-align: right;
width: var(--label-width);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
&[position="left"] {
height: 32px;
line-height: 32px;
}
&[position="top"] {
margin-bottom: 4px;
.bar-item-label {
width: 100%;
text-align: left;
}
.bar-item_content {
width: calc(100% - 80px);
}
}
.bar-item_content {
width: calc(100% - var(--label-width) - 80px);
.bar-item_content-bar {
width: 0;
height: 9px;
background: linear-gradient(270deg, #63e700 0%, #19674c 100%);
transition: width 0.3s;
}
}
.bar-item_remark {
font-size: 14px;
.text-success {
color: #09c700;
}
}
}
</style>

8
src/components/datav/statistic.vue

@ -15,7 +15,7 @@ const props = defineProps({
}, },
value: { value: {
type: Number, type: Number,
defalut: 0, default: 0,
}, },
valueUnit: { valueUnit: {
type: String, type: String,
@ -23,10 +23,10 @@ const props = defineProps({
// //
isDecimal: { isDecimal: {
type: String, type: String,
defalut: false default: false
} }
}); });
const value = ref(0); const value = ref(props.value);
watch(() => props.value, (val) => { watch(() => props.value, (val) => {
value.value = val; value.value = val;
}) })
@ -50,6 +50,7 @@ const outputValue = useTransition(value, {
rgba(3, 11, 57, 0) 100% rgba(3, 11, 57, 0) 100%
); );
margin-bottom: 14px; margin-bottom: 14px;
&::before, &::before,
&::after { &::after {
display: block; display: block;
@ -65,6 +66,7 @@ const outputValue = useTransition(value, {
); );
} }
} }
.statistic-title { .statistic-title {
font-size: 27px; font-size: 27px;
white-space: break-spaces; white-space: break-spaces;

10
src/views/data/Ajhc.vue

@ -47,7 +47,7 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="分发状态" > <el-form-item label="分发状态" >
<el-select v-model="query.distributionState"> <el-select v-model="query.distributionState" clearable>
<el-option <el-option
v-for="item in dict.distributionState" v-for="item in dict.distributionState"
:key="item.id" :key="item.id"
@ -61,9 +61,6 @@
<el-col :span="6"> <el-col :span="6">
<el-form-item label="是否属实"> <el-form-item label="是否属实">
<el-select <el-select
size="small"
style="width: 146px"
placeholder="核查情况"
clearable clearable
v-model="query.checkStatus" v-model="query.checkStatus"
> >
@ -139,12 +136,12 @@
/> />
<el-table-column <el-table-column
label="投诉人电话" label="投诉人电话"
prop="contactPhone" prop="responderPhone"
width="120" width="120"
/> />
<el-table-column label="业务类别" prop="businessTypeName"/> <el-table-column label="业务类别" prop="businessTypeName"/>
<el-table-column label="涉嫌问题" prop="involveProblem"/> <el-table-column label="涉嫌问题" prop="involveProblem"/>
<el-table-column label="涉及警种" prop="policeTypeName"/> <!-- <el-table-column label="涉及警种" prop="policeTypeName"/>-->
<el-table-column label="涉及单位" prop="thirdDepartName"/> <el-table-column label="涉及单位" prop="thirdDepartName"/>
<el-table-column <el-table-column
label="具体内容" label="具体内容"
@ -391,6 +388,7 @@ const dict = catchStore.getDicts([
"distributionState", "distributionState",
"timeLimit", "timeLimit",
"approvalFlow", "approvalFlow",
"inspectCase",
]); ]);
const query = ref({ const query = ref({

32
src/views/data/Mail12337.vue

@ -46,6 +46,25 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col :span="6">
<el-form-item label="是否属实">
<el-select
clearable
v-model="query.checkStatus"
>
<el-option
v-for="item in dict.inspectCase"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
<div class="mb-25 flex between"> <div class="mb-25 flex between">
<div> <div>
@ -112,6 +131,14 @@
prop="wjwfProject" prop="wjwfProject"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column label="是否属实" prop="isReal">
<template v-slot="scope">
<span v-if="scope.row.isReal === 1">属实</span>
<span v-else-if="scope.row.isReal === 2">部分属实</span>
<span v-else-if="scope.row.isReal === 3">不属实</span>
<span v-else>未知状态</span>
</template>
</el-table-column>
<el-table-column label="状态"> <el-table-column label="状态">
<template #default="{ row }"> <template #default="{ row }">
<el-tag>{{ <el-tag>{{
@ -210,13 +237,15 @@ const dict = catchStore.getDicts([
"approvalFlow", "approvalFlow",
"distributionFlow", "distributionFlow",
"distributionState", "distributionState",
"inspectCase",
]); ]);
const query = ref({ const query = ref({
size: 10, size: 10,
current: 1, current: 1,
responderKey: "name", responderKey: "name",
problemSourcesCode: ProblemSources.GABXF, problemSourcesCode: ProblemSources.XF12337,
}); });
const list = ref([]); const list = ref([]);
@ -238,6 +267,7 @@ function reset() {
}; };
getList(); getList();
} }
getList(); getList();
const show = ref(false); const show = ref(false);

204
src/views/datav/Gobal.vue

@ -5,60 +5,33 @@
<main> <main>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="6"> <el-col :span="6">
<datav-card title="督察问题"> <datav-card title="机构问题排名" sub-title="问题数">
<el-row class="mb-32">
<el-col :span="6"> <datav-tabs
<div class="descriptions_cell text-center"> v-model="activeOrgTab"
<div class="descriptions_content"> type="bottom-button"
4323 >
</div> <datav-tab-item label="分县市局" name="1">
<div class="descriptions_label"> <el-scrollbar height="300px">
问题数
</div>
</div>
</el-col>
<el-col :span="6">
<div class="descriptions_cell text-center">
<div class="descriptions_content">
4323
</div>
<div class="descriptions_label">
整改中
</div>
</div>
</el-col>
<el-col :span="6">
<div class="descriptions_cell text-center">
<div class="descriptions_content">
2356
</div>
<div class="descriptions_label">
已整改
</div>
</div>
</el-col>
<el-col :span="6">
<div class="descriptions_cell text-center">
<div class="descriptions_content">
91%
</div>
<div class="descriptions_label">
整改率
</div>
</div>
</el-col>
</el-row>
<datav-chart-bar <datav-chart-bar
title="整改率排名"
sub-title="完成数/问题数"
:data="data1" :data="data1"
size="large"
:max="11"
:color="colors"
/> />
<div class="flex tab-title flex center mt-16"> </el-scrollbar>
<div class="tab-title-item active"> </datav-tab-item>
分县市局 <datav-tab-item label="局属单位" name="2">
</div> <el-scrollbar height="300px">
<div class="tab-title-item">局属单位</div> <datav-chart-bar
</div> :data="data1"
:max="11"
size="large"
:color="colors"
/>
</el-scrollbar>
</datav-tab-item>
</datav-tabs>
</datav-card> </datav-card>
<datav-card title="警务评议"> <datav-card title="警务评议">
<el-row class="mb-32"> <el-row class="mb-32">
@ -117,45 +90,46 @@
</datav-card> </datav-card>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<div class="datav-col"> <datav-date-picker v-model="time"/>
<label for="">统计周期</label>
<span>2024年01月01日 - 2024年08月30日</span>
</div>
<div class="flex gap-42"> <div class="flex gap-42">
<datav-statistic <datav-statistic
:value="8683" :value="overview.totalPro"
title="问题总数" title="问题总数"
style="width: 20%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="4432" :value="overview.supervisionPro"
title="处理中" title="督察问题"
style="width: 20%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="801" :value="overview.caseVerificationPro"
title="涉及单位" title="案件核查问题"
style="width: 20%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="7001" :value="overview.mailComplaintPro"
title="涉及人员" title="信访投诉问题"
style="width: 20%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="91" :value="overview.policeValuationPro"
value-unit="%" title="警务评议问题"
title="办结率" style="width: 16.66%"
style="width: 20%"
/> />
</div> <datav-statistic
<div @click="go"> :value="overview.reviewPro"
<v-charts title="审计监督问题"
style="height: 450px" style="width: 16.66%"
:option="option"
autoresize
/> />
</div> </div>
<!-- <div @click="go">-->
<!-- <v-charts-->
<!-- style="height: 450px"-->
<!-- :option="option"-->
<!-- autoresize-->
<!-- />-->
<!-- </div>-->
<datav-card title="问题趋势"> <datav-card title="问题趋势">
<v-charts <v-charts
style="height: 300px" style="height: 300px"
@ -275,6 +249,9 @@
import vCharts from "vue-echarts"; import vCharts from "vue-echarts";
import changshaMap from "@/assets/data/changsha.json"; import changshaMap from "@/assets/data/changsha.json";
import * as echarts from "echarts/core"; import * as echarts from "echarts/core";
import moment from "moment/moment";
import {getCaseVerifData} from "@/api/datav";
import {getAllGobalCount} from "@/api/data/basicScreen.ts";
const router = useRouter(); const router = useRouter();
@ -389,57 +366,90 @@ const data1 = [
{ {
label: "开福分局", label: "开福分局",
value: 97, value: 97,
unit: "%",
numerator: 97,
denominator: 100,
}, },
{ {
label: "芙蓉分局", label: "芙蓉分局",
value: 90, value: 90,
unit: "%",
numerator: 90,
denominator: 100,
}, },
{ {
label: "岳麓分局", label: "岳麓分局",
value: 85, value: 85,
unit: "%",
numerator: 85,
denominator: 100,
}, },
{ {
label: "雨花分局", label: "雨花分局",
value: 80, value: 80,
unit: "%",
numerator: 80,
denominator: 100,
}, },
{ {
label: "望城分局", label: "望城分局",
value: 71, value: 71,
unit: "%",
numerator: 71,
denominator: 100,
}, },
{ {
label: "浏阳市局", label: "浏阳市局",
value: 66, value: 66,
unit: "%",
numerator: 66,
denominator: 100,
}, },
{ {
label: "长沙县局", label: "长沙县局",
value: 62, value: 62,
unit: "%",
numerator: 62,
denominator: 100,
}, },
]; ];
function go() { function go() {
router.push("/datav/sub1") router.push("/datav/sub1")
} }
// region
const activeOrgTab = ref("1");
// endregion
// region
const overview = ref({
totalPro: 0,
supervisionPro: 0,
caseVerificationPro: 0,
mailComplaintPro: 0,
policeValuationPro: 0,
reviewPro: 0,
});
const time = ref([
moment().startOf("year").format("YYYY-MM-DD"),
moment().format("YYYY-MM-DD"),
]);
function getData() {
getAllGobalCount(time.value).then((res) => {
console.log(res);
console.log(res.overview)
overview.value = res.overview;
});
}
watch(time, () => {
getData();
});
onMounted(() => {
getData();
});
const colors = [
{
color: "linear-gradient( 270deg, #FB002D 0%, #822232 100%)",
percentage: 80,
},
{
color: "linear-gradient( 270deg, #FFB90E 0%, #71501D 100%)",
percentage: 60,
},
{
color: "linear-gradient( 270deg, #63E700 0%, #19674C 100%)",
percentage: 40,
},
];
// endregion
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/style/datav.scss"; @import "@/style/datav.scss";

124
src/views/datav/SceneInsp.vue

@ -5,7 +5,7 @@
<main> <main>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="6"> <el-col :span="6">
<datav-card title="执勤值守情况"> <datav-card title="日常督察情况">
<el-row class="mb-32"> <el-row class="mb-32">
<el-col :span="6"> <el-col :span="6">
<div class="descriptions_cell text-center"> <div class="descriptions_cell text-center">
@ -48,17 +48,36 @@
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<datav-tabs
type="bottom-button"
v-model="activeTabLeft"
>
<datav-tab-item label="分县市局" name="1">
<el-scrollbar height="350px">
<datav-chart-bar-new
:data="data1"
size="large"
:color="colors"
title="整改率排名"
sub-title="完成数/问题数"
/>
</el-scrollbar>
</datav-tab-item>
<datav-tab-item label="局属单位" name="2">
<el-scrollbar height="350px">
<datav-chart-bar <datav-chart-bar
:data="jsdwBarList"
:max="11"
size="large"
:color="colors"
title="整改率排名" title="整改率排名"
sub-title="完成数/问题数" sub-title="完成数/问题数"
:data="data1"
/> />
<div class="flex tab-title flex center mt-16"> </el-scrollbar>
<div class="tab-title-item active"> </datav-tab-item>
分县市局 </datav-tabs>
</div>
<div class="tab-title-item">局属单位</div>
</div>
</datav-card> </datav-card>
<datav-card title="问题类型占比"> <datav-card title="问题类型占比">
<v-charts <v-charts
@ -69,38 +88,35 @@
</datav-card> </datav-card>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<div class="datav-col"> <datav-date-picker v-model="time"/>
<label for="">统计周期</label>
<span>2024年01月01日 - 2024年08月30日</span>
</div>
<div class="flex gap-42"> <div class="flex gap-42">
<datav-statistic <datav-statistic
:value="194" :value="overview.supervisionNotifyTotal"
title="通报问题数" title="通报问题数"
style="width: 16.66%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="2" :value="overview.supervisionNotifyChangingTotal"
title="整改中" title="整改中"
style="width: 16.66%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="192" :value="overview.supervisionNotifyChangedTotal"
title="已整改" title="已整改"
style="width: 16.66%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="73" :value="overview.supervisionNotifyOrgTotal"
title="涉及单位数" title="涉及单位数"
style="width: 16.66%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="214" :value="overview.supervisionNotifyPreTotal"
title="涉及人数" title="涉及人数"
style="width: 16.66%" style="width: 16.66%"
/> />
<datav-statistic <datav-statistic
:value="99" :value="overview.correctionRate"
value-unit="%" value-unit="%"
title="整改率" title="整改率"
style="width: 16.66%" style="width: 16.66%"
@ -220,6 +236,8 @@
import vCharts from "vue-echarts"; import vCharts from "vue-echarts";
import changshaMap from "@/assets/data/changsha.json"; import changshaMap from "@/assets/data/changsha.json";
import * as echarts from "echarts/core"; import * as echarts from "echarts/core";
import moment from "moment";
import {getAllSupervisionNotifyCount} from "@/api/data/supervisionNotify.ts";
echarts.registerMap("changsha", changshaMap); echarts.registerMap("changsha", changshaMap);
const option = { const option = {
@ -337,57 +355,57 @@ const option1 = ref({
], ],
}); });
const data1 = [ const data1 = ref([
{ {
name: "开福分局", label: "开福分局",
value: 100, value: 80,
unit: "%", unit: "%",
numerator: 16, numerator: 16,
denominator: 16, denominator: 17,
}, },
{ {
name: "芙蓉分局", label: "芙蓉分局",
value: 100, value: 100,
unit: "%", unit: "%",
numerator: 11, numerator: 11,
denominator: 11, denominator: 11,
}, },
{ {
name: "岳麓分局", label: "岳麓分局",
value: 100, value: 100,
unit: "%", unit: "%",
numerator: 10, numerator: 10,
denominator: 10, denominator: 10,
}, },
{ {
name: "雨花分局", label: "雨花分局",
value: 100, value: 100,
unit: "%", unit: "%",
numerator: 9, numerator: 9,
denominator: 9, denominator: 9,
}, },
{ {
name: "望城分局", label: "望城分局",
value: 100, value: 100,
unit: "%", unit: "%",
numerator: 4, numerator: 4,
denominator: 4, denominator: 4,
}, },
{ {
name: "浏阳市局", label: "浏阳市局",
value: 100, value: 100,
unit: "%", unit: "%",
numerator: 3, numerator: 3,
denominator: 3, denominator: 3,
}, },
{ {
name: "长沙县局", label: "长沙县局",
value: 100, value: 100,
unit: "%", unit: "%",
numerator: 3, numerator: 3,
denominator: 3, denominator: 3,
}, },
]; ]);
const data2 = [ const data2 = [
{ {
@ -442,6 +460,54 @@ const option2 = {
}, },
], ],
}; };
// region
const activeTabLeft = ref("1");
const overview = ref({
supervisionNotifyTotal: 0,
supervisionNotifyOrgTotal: 0,
supervisionNotifyPreTotal: 0,
supervisionNotifyChangingTotal: 0,
supervisionNotifyChangedTotal: 0,
correctionRate: 0,
});
const time = ref([
moment().startOf("year").format("YYYY-MM-DD"),
moment().format("YYYY-MM-DD"),
]);
function getData() {
getAllSupervisionNotifyCount(time.value).then((res) => {
overview.value = res.overview;
});
}
watch(time, () => {
getData();
});
onMounted(() => {
getData();
});
const colors = [
{
color: "linear-gradient( 270deg, #FB002D 0%, #822232 100%)",
percentage: 80,
},
{
color: "linear-gradient( 270deg, #FFB90E 0%, #71501D 100%)",
percentage: 60,
},
{
color: "linear-gradient( 270deg, #63E700 0%, #19674C 100%)",
percentage: 40,
},
];
// endregion
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/style/datav.scss"; @import "@/style/datav.scss";

Loading…
Cancel
Save