Browse Source

fit: 案件核查大屏。 fit: 警务人员增加角色 fit: 首页增加下钻到综合查询

main
wxc 1 year ago
parent
commit
07662633c6
  1. 50
      src/components/datav/chart-bar.vue
  2. 34
      src/views/Home.vue
  3. 255
      src/views/datav/CaseVerif.vue
  4. 26
      src/views/sensitivePerception/ModelClue.vue
  5. 2
      src/views/system/DictContent.vue
  6. 84
      src/views/system/Police.vue
  7. 19
      src/views/work/Query.vue

50
src/components/datav/chart-bar.vue

@ -4,8 +4,12 @@
<span class="bar-sub-title">{{ subTitle }}</span>
</div>
<div>
<div class="flex v-center bar-item between" v-for="item in data" :size="size">
<span class="bar-item-name mr-10">{{ item.name }}</span>
<div
class="flex v-center bar-item between"
v-for="item in data"
:size="size"
>
<span class="bar-item-name mr-10">{{ item.label }}</span>
<div class="bar-item_content mr-16">
<div
class="bar-item_content-bar"
@ -15,8 +19,12 @@
}"
></div>
</div>
<span class="mr-16">{{ item.value }}{{ item.unit }}</span>
<span class="bar-item_remark text-right" v-if="item.denominator" style="min-width: 40px">
<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>
@ -25,7 +33,9 @@
</div>
</template>
<script setup>
defineProps({
import { onMounted } from "vue";
const props = defineProps({
title: {
type: String,
default: "",
@ -38,16 +48,34 @@ defineProps({
type: Array,
default: [],
},
max: {
type: Number,
default: 100,
},
size: {
type: String,
default: "",
},
unit: {
type: String,
default: "",
},
});
const max = ref(100);
watch(
() => props.data,
(arr) => {
getMax()
}
);
function getMax() {
if (props.unit !== "%") {
max.value = Math.max(...props.data.map((item) => item.value));
}
}
onMounted(() => {
getMax()
})
function getColor(val) {
if (val > 0.8) {
return "linear-gradient(270deg, #63e700 0%, #19674c 100%)";
@ -70,7 +98,7 @@ function getColor(val) {
font-size: 17px;
height: 32px;
&[size="large"] {
height: 46px;
height: 42px;
.bar-item_content {
.bar-item_content-bar {
height: 13px;
@ -88,7 +116,7 @@ function getColor(val) {
height: 9px;
background: linear-gradient(270deg, #63e700 0%, #19674c 100%);
box-shadow: 1px 0 0px 0px #020b5f;
transition: width .3s;
transition: width 0.3s;
}
}
.bar-item_remark {

34
src/views/Home.vue

@ -7,6 +7,7 @@
:span="6"
v-for="(item, index) in flowNumber"
:key="index"
@click="goQuery(item)"
>
<section class="flex column v-center overall-item pointer">
<div>
@ -26,7 +27,7 @@
<h2 class="text-bold">今日统计</h2>
</div>
<div class="flex wrap box">
<section class="flex column v-center daily-item pointer" v-for="item in todayNumber" :key="item.name">
<section class="flex column v-center daily-item pointer" v-for="item in todayNumber" :key="item.name" @click="goQuery2(item)">
<div class="number">{{ item.total }}</div>
<span>{{ item.name }}</span>
</section>
@ -56,6 +57,37 @@ flowNumberAndTodayNumber().then(data => {
todayNumber.value = data.todayNumber;
})
const links = ['警务评议', '视频督察', '情指行', '执法办案']
const router = useRouter()
function goQuery(item) {
if (item.icon === 'sign') {
router.push('/query?processingStatus=signing')
}
if (item.icon === 'verify') {
router.push('/query?processingStatus=processing')
}
if (item.icon === 'delay') {
router.push('/query?processingStatus=signing')
}
if (item.icon === 'completedApprove') {
router.push('/query?processingStatus=approval')
}
}
function goQuery2(item) {
if (item.name === '今日问题') {
router.push('/query?crtTime=today')
}
if (item.name === '今日办结') {
}
if (item.name === '累计问题') {
router.push('/query')
}
if (item.name === '累计办结') {
router.push('/query?processingStatus=completed')
}
}
</script>
<style lang="scss" scoped>
.overall-item {

255
src/views/datav/CaseVerif.vue

@ -12,14 +12,13 @@
>
<datav-tab-item label="分县市局" name="1">
<datav-chart-bar
:data="data1"
:max="11"
:data="fxsjBarList"
size="large"
/>
</datav-tab-item>
<datav-tab-item label="局属单位" name="2">
<datav-chart-bar
:data="data1"
:data="jsdwBarList"
:max="11"
size="large"
/>
@ -30,16 +29,24 @@
<datav-tabs v-model="activeTab">
<datav-tab-item label="执法办案" name="1">
<v-charts
style="height: 340px"
:option="option2"
style="height: 320px"
:option="zfbaPieOption"
autoresize
/>
</datav-tab-item>
<datav-tab-item label="服务管理" name="2">
<v-charts
style="height: 320px"
:option="fwglPieOption"
autoresize
/>
</datav-tab-item>
<datav-tab-item label="警纪警规" name="3">
<v-charts
style="height: 320px"
:option="jjjgPieOption"
autoresize
/>
</datav-tab-item>
</datav-tabs>
</datav-card>
@ -80,13 +87,13 @@
/>
</div>
<v-charts
style="height: 400px"
style="height: 420px"
:option="option"
autoresize
/>
<datav-card title="查处问题趋势">
<v-charts
style="height: 280px"
style="height: 320px"
:option="option1"
autoresize
/>
@ -96,11 +103,13 @@
<datav-card>
<datav-tabs v-model="activeTab">
<datav-tab-item label="案件来源占比" name="1">
<v-charts
style="height: 340px"
:option="option3"
autoresize
/>
<div class="mb-40">
<v-charts
style="height: 340px"
:option="ajlyPieOption"
autoresize
/>
</div>
</datav-tab-item>
<datav-tab-item label="问责处理情况" name="2">
</datav-tab-item>
@ -109,11 +118,13 @@
<datav-card>
<datav-tabs v-model="activeTab">
<datav-tab-item label="停职处理情况" name="1">
<v-charts
style="height: 340px"
:option="option4"
autoresize
/>
<div class="mb-40">
<v-charts
style="height: 340px"
:option="option4"
autoresize
/>
</div>
</datav-tab-item>
<datav-tab-item label="禁闭处理情况" name="2">
</datav-tab-item>
@ -129,10 +140,13 @@
import vCharts from "vue-echarts";
import changshaMap from "@/assets/data/changsha.json";
import * as echarts from "echarts/core";
import moment from 'moment'
import { getCaseVerifData } from '@/api/datav'
import moment from "moment";
import { getCaseVerifData } from "@/api/datav";
const time = ref([moment().startOf('year').format('YYYY-MM-DD'), moment().format('YYYY-MM-DD')])
const time = ref([
moment().startOf("year").format("YYYY-MM-DD"),
moment().format("YYYY-MM-DD"),
]);
const overview = ref({
total: 0,
@ -140,19 +154,95 @@ const overview = ref({
investigateAndPunish: 0,
accountablePeopleNumber: 0,
accountableDepartNumber: 0,
confirmedRate: 0
})
confirmedRate: 0,
});
const fxsjBarList = ref([]);
const jsdwBarList = ref([]);
const zfbaPieList = ref([]);
const fwglPieList = ref([]);
const jjjgPieList = ref([]);
const ajlyPieList = ref([]);
function getData() {
getCaseVerifData(time.value).then(data => {
overview.value = data.overview
})
getCaseVerifData(time.value).then((data) => {
overview.value = data.overview;
fxsjBarList.value = data.fxsjBarList;
jsdwBarList.value = data.jsdwBarList;
zfbaPieList.value = data.zfbaPieList;
fwglPieList.value = data.fwglPieList;
jjjgPieList.value = data.jjjgPieList;
ajlyPieList.value = data.ajlyPieList;
});
}
onMounted(() => {
getData()
watch(time, () => {
getData();
})
onMounted(() => {
getData();
});
const zfbaPieOption = computed(() => {
return {
series: [
{
type: "pie",
radius: ["40%", "70%"],
label: {
color: "#fff",
},
data: zfbaPieList.value,
},
],
};
});
const fwglPieOption = computed(() => {
return {
series: [
{
type: "pie",
radius: ["40%", "70%"],
label: {
color: "#fff",
},
data: fwglPieList.value,
},
],
};
});
const jjjgPieOption = computed(() => {
return {
series: [
{
type: "pie",
radius: ["40%", "70%"],
label: {
color: "#fff",
},
data: jjjgPieList.value,
},
],
};
});
const ajlyPieOption = computed(() => {
return {
series: [
{
type: "pie",
radius: ["40%", "70%"],
label: {
color: "#fff",
},
data: ajlyPieList.value,
},
],
};
});
echarts.registerMap("changsha", changshaMap);
const option = {
@ -160,7 +250,6 @@ const option = {
// registerMap''
map: "changsha",
},
visualMap: {
type: "piecewise",
bottom: 10,
@ -192,9 +281,7 @@ const option = {
color: "white",
},
itemStyle: {
normal: {
areaColor: "#02215E", //
},
areaColor: "#02215E", //
},
},
],
@ -261,108 +348,6 @@ const option1 = ref({
],
});
const data1 = [
{
name: "开福分局",
value: 11,
},
{
name: "芙蓉分局",
value: 9,
},
{
name: "岳麓分局",
value: 7,
},
{
name: "雨花分局",
value: 4,
},
{
name: "望城分局",
value: 3,
},
{
name: "浏阳市局",
value: 3,
},
{
name: "长沙县局",
value: 1,
},
];
const data2 = [
{
name: "开福分局",
value: 9700,
},
{
name: "芙蓉分局",
value: 9021,
},
{
name: "岳麓分局",
value: 8512,
},
{
name: "雨花分局",
value: 8021,
},
{
name: "望城分局",
value: 7111,
},
{
name: "浏阳市局",
value: 6622,
},
{
name: "长沙县局",
value: 6221,
},
];
const option2 = {
series: [
{
type: "pie",
radius: ["40%", "70%"],
label: {
color: "#fff",
},
data: [
{ value: 311, name: "违规办案" },
{ value: 735, name: "不作为" },
{ value: 580, name: "乱作为" },
{ value: 484, name: "慢作为" },
{ value: 300, name: "暴力执法" },
{ value: 300, name: "执法不规范" },
],
},
],
};
const option3 = {
series: [
{
type: "pie",
radius: ["40%", "70%"],
label: {
color: "#fff",
},
data: [
{ value: 311, name: "自办" },
{ value: 735, name: "13489" },
{ value: 580, name: "队领导交办" },
{ value: 484, name: "局领导交办" },
{ value: 300, name: "公安部领导交办" },
{ value: 300, name: "市局主要领导交办" },
],
},
],
};
const option4 = {
series: [
{

26
src/views/sensitivePerception/ModelClue.vue

@ -79,7 +79,7 @@
width="200"
>
<template #default="{ row }">
<span>{{ row.involveParentDepartName }}</span> <span>{{ row.involveDepartName }}</span>
<span>{{ activeModelClue.involveParentDepartName }}</span><span>{{ activeModelClue.involveDepartName ? '/' + activeModelClue.involveDepartName : '' }}</span>
</template>
</el-table-column>
<el-table-column
@ -114,6 +114,13 @@
@click="handleShowDetail(row)"
>查看详情</el-button
>
<el-button
v-if="row.negativeId"
type="primary"
link
@click="handleAction(row)"
>处理详情</el-button
>
</template>
</el-table-column>
</el-table>
@ -150,7 +157,7 @@
<div class="col col-6">
<label>涉及单位</label>
<span>
<span>{{ activeModelClue.involveParentDepartName }}</span> <span>{{ activeModelClue.involveDepartName }}</span>
<span>{{ activeModelClue.involveParentDepartName }}</span><span>{{ activeModelClue.involveDepartName ? '/' + activeModelClue.involveDepartName : '' }}</span>
</span>
</div>
<div class="col col-6">
@ -181,6 +188,12 @@
</div>
</div>
</el-dialog>
<negative-dialog
v-model="negativeShow"
:id="activeNegativeId"
@close="negativeShow = false"
/>
</template>
<script lang="ts" setup>
import { listModelClue } from "@/api/sensitivePerception/modelClue";
@ -232,6 +245,15 @@ function handleShowDetail(row) {
activeModelClue.value = row;
show.value = true;
}
const activeNegativeId = ref('')
const negativeShow = ref(false)
function handleAction(row) {
negativeShow.value = true;
activeNegativeId.value = row.negativeId;
}
</script>
<style lang="scss" scoped>
</style>

2
src/views/system/DictContent.vue

@ -14,9 +14,7 @@
<div class="table-container">
<el-table :data="dictContents" row-key="id">
<el-table-column label="类型名称" prop="name" show-overflow-tooltip="" />
<el-table-column label="类型编码" prop="code" width="200" />
<el-table-column label="序号" prop="sort" width="200" />
<el-table-column label="序号" prop="level" width="200" />
<el-table-column label="最后更新时间" prop="updTime" />
<el-table-column label="操作">
<template #default="{ row }">

84
src/views/system/Police.vue

@ -59,6 +59,22 @@
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="权限角色">
<el-select
v-model="query.roleId"
placeholder="请选择角色"
clearable
>
<el-option
v-for="item in roles"
:key="item.roleId"
:value="item.roleId"
:label="item.roleName"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="mb-25 flex between">
@ -99,6 +115,16 @@
)
}}</span>
</div>
<div class="col col-6">
<label>备注</label>
<span>{{ row.job }}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-6">
<label>电话</label>
<span>{{ row.mobile }}</span>
</div>
<div class="col col-6">
<label>入职时间</label>
<span>{{ row.employmentDate }}</span>
@ -136,7 +162,9 @@
<el-table-column label="所属机构" show-overflow-tooltip>
<template #default="{ row }">
<div class="flex gap-4">
<span v-if="row.parentDepartShortName">{{ row.parentDepartShortName }}/</span><span>{{ row.departShortName }}</span>
<span v-if="row.parentDepartShortName"
>{{ row.parentDepartShortName }}/</span
><span>{{ row.departShortName }}</span>
</div>
</template>
</el-table-column>
@ -147,20 +175,34 @@
}}</span>
</template>
</el-table-column>
<el-table-column label="职位" prop="position" width="120" align="center" >
<el-table-column label="职位" width="120" align="center">
<template #default="{ row }">
<span v-if="row.position">
<span v-if="row.level === 0">局领导{{ row.position }}</span>
<span v-if="row.level === 2">二级机构{{ row.position }}</span>
<span v-if="row.level === 3">三机机构{{ row.position }}</span>
<span v-if="row.level === 4">四机机构{{ row.position }}</span>
<span v-if="row.level === 0"
>局领导{{ row.position }}</span
>
<span v-if="row.level === 2"
>二级机构{{ row.position }}</span
>
<span v-if="row.level === 3"
>三机机构{{ row.position }}</span
>
<span v-if="row.level === 4"
>四机机构{{ row.position }}</span
>
</span>
</template>
</el-table-column>
<el-table-column label="备注" prop="job" width="140" show-overflow-tooltip />
<el-table-column label="身份证" prop="idCode" width="200" />
<el-table-column label="电话" prop="mobile" width="120" show-overflow-tooltip />
<el-table-column label="角色" show-overflow-tooltip>
<template #default="{ row }">
<div class="flex gap" v-if="row.role">
<el-tag v-for="item in row.role.split(',')">{{
item
}}</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="220">
<template #default="{ row }">
@ -229,7 +271,6 @@
filterable
v-model="authForm.sources"
multiple
/>
</el-form-item>
</el-form>
@ -304,7 +345,7 @@
}"
>
<div style="width: 280px">
<depart-tree-select v-model="form.orgId" :showRoot="true" />
<depart-tree-select v-model="form.orgId" :showRoot="true" />
</div>
</el-form-item>
<el-form-item label="人员属性">
@ -317,7 +358,11 @@
>
</el-radio-group>
</el-form-item>
<el-form-item label="职位" prop="position" v-if="form.personType === PersonType.POLICE">
<el-form-item
label="职位"
prop="position"
v-if="form.personType === PersonType.POLICE"
>
<el-select
v-model="form.position"
clearable
@ -409,7 +454,8 @@ import {
delPolice,
updatePoliceAuths,
} from "@/api/system/police";
import { PersonType } from '@/enums/dictEnums'
import { listRole } from "@/api/system/role";
import { PersonType } from "@/enums/dictEnums";
import useCatchStore from "@/stores/modules/catch";
import feedback from "@/utils/feedback";
import { getDictLable } from "@/utils/util";
@ -443,8 +489,12 @@ function getList() {
});
}
const roles = ref([]);
onMounted(() => {
getList();
listRole().then((data) => {
roles.value = data;
});
});
function reset() {
@ -529,10 +579,10 @@ function getWorkYear(employmentDate) {
}
async function handleDel(row) {
await feedback.confirm(`确定要删除 ${row.name}`)
await delPolice(row.id)
feedback.msgSuccess('操作成功')
getList()
await feedback.confirm(`确定要删除 ${row.name}`);
await delPolice(row.id);
feedback.msgSuccess("操作成功");
getList();
}
</script>
<style lang="scss" scoped>

19
src/views/work/Query.vue

@ -446,11 +446,11 @@
<negative-dialog
v-model="show"
:id="activeNegativeId"
@change="getList"
@close="show = false"
/>
</template>
<script setup>
import moment from "moment";
import { ElLoading } from "element-plus";
import { listNegative, negativeExport, delNegative } from "@/api/work/negative";
import { getDictLable, formatTimeText, getInvolveProblem } from "@/utils/util";
@ -497,8 +497,25 @@ function reset() {
responderKey: "name",
};
getList();
//
router.push('/query')
}
const route = useRoute()
watch(() => route.query, () => {
if (route.query.processingStatus) {
query.value.processingStatus = [route.query.processingStatus]
} else {
query.value.processingStatus = []
}
if (route.query.crtTime === 'today') {
query.value.crtTime = [moment().startOf("day").format("YYYY-MM-DD HH:mm:ss"), moment().endOf("day").format("YYYY-MM-DD HH:mm:ss")]
} else {
query.value.crtTime = []
}
getList()
})
onMounted(() => {
getList();
});

Loading…
Cancel
Save