Browse Source

20250410

main
wxc 10 months ago
parent
commit
6da19f7613
  1. 2
      src/api/data/supervisionNotify.ts
  2. 15
      src/api/mobileSupervision/inspection.ts
  3. 22
      src/api/mobileSupervision/testingAlcohol.ts
  4. 3
      src/api/screen/gobal.ts
  5. 2
      src/api/screen/jwpy.ts
  6. 8
      src/api/screen/rightsComfort.ts
  7. 2
      src/api/screen/videoSupervise.ts
  8. 9
      src/api/work/negative.ts
  9. 14
      src/api/work/negativeTask.ts
  10. 22097
      src/assets/data/changsha.json
  11. 22096
      src/assets/data/changsha2.json
  12. 2
      src/components/data/gj-import.vue
  13. 269
      src/components/datav/chart-bar-pro.vue
  14. 4
      src/components/home/work/index.vue
  15. 2
      src/components/negative/add.vue
  16. 16
      src/components/negative/description.vue
  17. 9
      src/components/negative/verify-description.vue
  18. 199
      src/components/negative/verify.vue
  19. 2
      src/components/negativeInfo/police-dialog.vue
  20. 216
      src/components/police-picker.vue
  21. 2
      src/layout/components/Header.vue
  22. 2
      src/utils/util.ts
  23. 2
      src/views/books/Ajhc.vue
  24. 4
      src/views/books/Gabxf.vue
  25. 6
      src/views/books/Gjxf.vue
  26. 89
      src/views/data/Ajhc.vue
  27. 137
      src/views/data/Gabxf.vue
  28. 164
      src/views/data/Gjxf.vue
  29. 87
      src/views/data/Mail12337.vue
  30. 2
      src/views/data/Mailbox.vue
  31. 5
      src/views/data/VideoInspection.vue
  32. 1224
      src/views/datav/Global.vue
  33. 6
      src/views/datav/Jwpy.vue
  34. 2
      src/views/datav/MailVisits.vue
  35. 15
      src/views/datav/RightsComfort.vue
  36. 6
      src/views/datav/SceneInsp.vue
  37. 128
      src/views/datav/VideoInsp.vue
  38. 20
      src/views/datav/subonedatav/SubOneGlobal.vue
  39. 2
      src/views/datav/subonedatav/SubOneMailVisits.vue
  40. 6
      src/views/datav/subonedatav/SubOneSceneInsp.vue
  41. 115
      src/views/datav/subonedatav/SubOneVideoInsp.vue
  42. 278
      src/views/mobileSupervise/Inspection.vue
  43. 469
      src/views/mobileSupervise/TestingAlcohol.vue
  44. 2
      src/views/sensitivePerception/PoliceNegative.vue
  45. 408
      src/views/work/BatchDistribute.vue

2
src/api/data/supervisionNotify.ts

@ -13,7 +13,7 @@ export function getSupervisionNotifyCount(times) {
}
/**
*
*
*/
export function getProblemTypeRate(times) {
return request.get({

15
src/api/mobileSupervision/inspection.ts

@ -0,0 +1,15 @@
import request from "@/api/request";
export function addInspection(body) {
return request.post({
url: '/task/inspection',
body
});
}
export function listInspection(query) {
return request.get({
url: '/task/inspection',
query
});
}

22
src/api/mobileSupervision/testingAlcohol.ts

@ -0,0 +1,22 @@
import request from "@/api/request";
export function getPersonNumber(query) {
return request.get({
url: '/task/testingAlcohol/getPersonNumber',
query
});
}
export function addTestingAlcohol(body) {
return request.post({
url: '/task/testingAlcohol',
body
});
}
export function listTestingAlcohol(query) {
return request.get({
url: '/task/testingAlcohol',
query
});
}

3
src/api/screen/gobal.ts

@ -58,9 +58,8 @@ export function getStrongProblemRate(times) {
});
}
/**
*
*
* @param year
*/
export function getProblemBusinessRate(times) {

2
src/api/screen/jwpy.ts

@ -31,7 +31,7 @@ export function GetZHMYLPM(PeriodId, PeriodSonID, OrgId, TaskID, TaskClass) {
formData.append("PeriodSonID", PeriodSonID);
OrgId && formData.append("OrgId", OrgId);
TaskID && formData.append("TaskID", TaskID);
formData.append("TaskClass", 1);
formData.append("TaskClass", TaskClass);
return outrequest.post({
url: `/out-police-service/api/DSJ/GetZHMYLPM`,
body: formData

8
src/api/screen/rightsComfort.ts

@ -1,7 +1,5 @@
import request from "../request";
export function getRightsAndComfortRank(times) {
return request.get({
url: `/datav/rightsComfort/getRightsAndComfortRank?beginTime=${times[0]}&endTime=${times[1]}`
@ -14,12 +12,6 @@ export function getCaseTypeRate(times) {
});
}
export function getALlComfortCount(times) {
return request.get({
url: `/datav/rightsComfort/getALlComfortCount?beginTime=${times[0]}&endTime=${times[1]}`

2
src/api/screen/videoSupervise.ts

@ -30,7 +30,7 @@ export function getVideoSuperviseTrend(year) {
}
// 视频督察大屏问题类型占比
// 视频督察大屏问题涉及方面分布
export function getVideoSuperviseProblemTypeRate(times) {
return request.get({
url: `/datav/videoSupervise/getVideoSuperviseProblemTypeRate?beginTime=${times[0]}&endTime=${times[1]}`

9
src/api/work/negative.ts

@ -94,4 +94,11 @@ export function verifySubmitNegative(id, body) {
url: `/negative/${id}/verifySubmit`,
body
});
}
}
// 通过来源ID获取ID
export function getIdByOriginId(originId) {
return request.get({
url: `/negative/getIdByOriginId/${originId}`
});
}

14
src/api/work/negativeTask.ts

@ -25,4 +25,18 @@ export function listGroupByDepart(id) {
return request.get({
url: `/negativeTask/${id}/byDepart`
});
}
export function importAuditNegative(body) {
return request.post({
url: `/negativeTask/audit/import`,
body
});
}
export function distributeAuditNegative(body) {
return request.post({
url: `/negativeTask/audit/distribute`,
body
});
}

22097
src/assets/data/changsha.json

File diff suppressed because one or more lines are too long

22096
src/assets/data/changsha2.json

File diff suppressed because it is too large Load Diff

2
src/components/data/gj-import.vue

@ -1,5 +1,5 @@
<template>
<el-dialog title="国家信访投诉导入" width="80vw" ref="dialogRef">
<el-dialog title="国家信访投诉导入" width="80vw" ref="dialogRef" :lock-scroll="false">
<header class="flex center mb-40">
<el-steps
:space="300"

269
src/components/datav/chart-bar-pro.vue

@ -1,195 +1,192 @@
<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 wrap between "
v-for="item in data"
:size="size"
:style="{ '--label-width': `${labelWidth}px` }"
:position="labelPosition"
style="height: 40px"
>
<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 wrap between"
v-for="item in data"
:size="size"
:style="{ '--label-width': `${labelWidth}px` }"
:position="labelPosition"
style="height: 40px"
>
<span style="margin-left: 18px">
{{ item.sort }}
</span>
<div class="bar-item_content mr-8 " :long="!item.denominator">
<span>{{ item.label }}</span>
<div
class="bar-item_content-bar"
:style="{
<div class="bar-item_content mr-8" :long="!item.denominator">
<span :title="item.label">{{ item.label }}</span>
<div
class="bar-item_content-bar"
:style="{
width: `${(item.value / max) * 100}%`,
background: getColor((item.value / max) * 100),
}"
></div>
</div>
<span>{{ item.value }}</span>
<span
class="bar-item_remark text-right ml-8"
v-if="item.denominator"
style="min-width: 40px"
>
></div>
</div>
<span>{{ item.value }}</span>
<span
class="bar-item_remark text-right ml-8"
v-if="item.denominator"
style="min-width: 40px"
>
<span class="text-success">{{ item.numerator }}</span>
<span>/</span>
<span>{{ item.denominator }}</span>
</span>
</div>
</div>
</div>
</template>
<script setup>
import {onMounted} from "vue";
import { onMounted } 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,
default: "linear-gradient(270deg, #63e700 0%, #19674c 100%)",
},
labelWidth: {
type: Number,
default: 60,
},
labelPosition: {
type: String,
default: "left",
},
title: {
type: String,
default: "",
},
subTitle: {
type: String,
default: "",
},
data: {
type: Array,
default: [],
},
size: {
type: String,
default: "",
},
unit: {
type: String,
default: "",
},
color: {
type: Object,
default: "linear-gradient(270deg, #63e700 0%, #19674c 100%)",
},
labelWidth: {
type: Number,
default: 60,
},
labelPosition: {
type: String,
default: "left",
},
});
const max = ref(100);
watch(
() => props.data,
() => {
getMax();
getMax();
}
);
function getMax() {
if (props.unit !== "%") {
max.value = Math.max(...props.data.map((item) => item.value));
}
if (props.unit !== "%") {
max.value = Math.max(...props.data.map((item) => item.value));
}
}
onMounted ( () => {
getMax();
onMounted(() => {
getMax();
});
function getColor(val) {
if (props.color instanceof String) {
return props.color;
}
if (props.color instanceof Array) {
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;
}
if (props.color instanceof String) {
return props.color;
}
}
return "linear-gradient(270deg, #63e700 0%, #19674c 100%)";
// if (val >= 0.7) {
// return "linear-gradient( 270deg, #FFB90E 0%, #71501D 100%)";
// }
// return "linear-gradient( 270deg, #FB002D 0%, #822232 100%)";
if (props.color instanceof Array) {
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%)";
// if (val >= 0.7) {
// return "linear-gradient( 270deg, #FFB90E 0%, #71501D 100%)";
// }
// return "linear-gradient( 270deg, #FB002D 0%, #822232 100%)";
}
</script>
<style lang="scss" scoped>
.bar-title {
font-size: 19px;
font-size: 19px;
}
.bar-sub-title {
color: #597ae9;
font-size: 14px;
color: #597ae9;
font-size: 14px;
}
.bar-item {
font-size: 17px;
&[size="large"] {
.bar-item_content {
.bar-item_content-bar {
height: 13px;
}
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;
&[size="small"] {
font-size: 12px;
}
.bar-item-label {
width: 100%;
text-align: left;
text-align: right;
width: var(--label-width);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.bar-item_content {
width: calc(100% - 80px);
&[position="left"] {
height: 32px;
line-height: 32px;
white-space: nowrap;
width: 100%;
}
}
.bar-item_content {
width: calc(100% - var(--label-width) - 16px - 30px);
&[position="top"] {
margin-bottom: 4px;
.bar-item-label {
width: 100%;
text-align: left;
}
&[long=false] {
width: calc(100% - var(--label-width) - 36px - 58px);
.bar-item_content {
width: calc(100% - 80px);
}
}
.bar-item_content-bar {
width: 0;
height: 9px;
background: linear-gradient(270deg, #63e700 0%, #19674c 100%);
transition: width 0.3s;
.bar-item_content {
width: calc(100% - var(--label-width) - 16px - 30px);
overflow: hidden;
text-overflow: ellipsis;
&[long="false"] {
width: calc(100% - var(--label-width) - 36px - 58px);
}
.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;
.bar-item_remark {
font-size: 14px;
.text-success {
color: #09c700;
.text-success {
color: #09c700;
}
}
}
}
</style>

4
src/components/home/work/index.vue

@ -35,9 +35,9 @@
<el-tab-pane name="comfort">
<template #label>
<el-badge :value="myComfortTotal" v-if="comforts.length">
<span class="tab-nav-title">我的抚慰</span>
<span class="tab-nav-title">抚慰申请</span>
</el-badge>
<span class="tab-nav-title" v-else>我的抚慰</span>
<span class="tab-nav-title" v-else>抚慰申请</span>
</template>
<div v-loading="comfortLoading" class="pt-20">
<home-work-my-comfort :data="comforts" @update="getComfortList" />

2
src/components/negative/add.vue

@ -1,7 +1,7 @@
<template>
<el-dialog
title="问题下发"
width="54vw"
width="1024px"
:lock-scroll="false"
top="5vh"
style="margin-bottom: 0"

16
src/components/negative/description.vue

@ -22,6 +22,14 @@
<label>问题来源</label>
<span>{{ negative.problemSources }}</span>
</div>
<div class="col col-6" v-if="negative.projectName">
<label>项目名称</label>
<span>{{ negative.projectName }}</span>
</div>
<div class="col col-6" v-if="negative.involveMoney">
<label>问题金额</label>
<span>{{ negative.involveMoney }}万元</span>
</div>
<div class="col col-6" v-if="negative.responderName">
<label>投诉反映人</label>
<span>{{ negative.responderName }}</span>
@ -46,14 +54,14 @@
<label>涉及警种</label>
<span>{{ negative.policeTypeName }}</span>
</div>
<div class="col col-6">
<label>涉及单位</label>
<span>{{ negative.involveDepartName || '/' }}</span>
</div>
<div class="col col-12">
<label>涉嫌问题</label>
<span>{{ getInvolveProblem(negative.involveProblem, dict.suspectProblem) || '/' }}</span>
</div>
<div class="col col-12">
<label>涉及单位</label>
<span>{{ negative.involveDepartName || '/' }}</span>
</div>
<div class="col col-6">
<label>创建时间</label>
<span>{{ negative.crtTime }}</span>

9
src/components/negative/verify-description.vue

@ -27,6 +27,7 @@
<label>整改限制</label>
<span>{{ `${negative.rectifyRestrictionDays}` }}</span>
</div>
</div>
<div class="row" v-if="negative.checkStatusDesc">
<div class="col col-24">
@ -46,8 +47,12 @@
<span>{{ negative.unrectifyReason }}</span>
</div>
</div>
<div class="row" v-if="negative.handlePolices.length > 0">
<div class="col col-24">
<div class="row" >
<div class="col col-6" v-if="negative.resolveSituation">
<label>化解情况</label>
<span>{{ negative.resolveSituation }}</span>
</div>
<div class="col col-18" v-if="negative.handlePolices.length > 0">
<label>经办人</label>
<span>
<div v-for="item in negative.handlePolices" :key="item" class="mr-20">

199
src/components/negative/verify.vue

@ -68,8 +68,7 @@
trigger: ['blur'],
}"
v-if="
form.checkStatus !== InspectCase.FALSE &&
form.checkStatus !== InspectCase.UNABLE
problemIsTrue && form.checkStatus !== InspectCase.UNABLE
"
>
<el-radio-group
@ -119,7 +118,7 @@
<el-col
:span="12"
v-if="
form.checkStatus !== InspectCase.FALSE &&
problemIsTrue &&
form.isRectifyCode === IsRectify.NOT &&
form.checkStatus !== InspectCase.UNABLE
"
@ -178,10 +177,7 @@
<el-form-item
label="问题整改情况"
prop="rectifyDesc"
v-if="
form.checkStatus !== InspectCase.FALSE &&
form.isRectifyCode === InspectCase.TRUE
"
v-if="problemIsTrue && form.isRectifyCode === InspectCase.TRUE"
:rules="{
required: true,
message: '请输入问题整改情况',
@ -195,6 +191,33 @@
:autosize="{ minRows: 4 }"
/>
</el-form-item>
<el-form-item
label="化解情况"
prop="resolveSituation"
v-if="
negative.problemSourcesCode === ProblemSources.GJXFPT ||
negative.problemSourcesCode === ProblemSources.GABXF
"
:rules="{
required: true,
message: '请选择信访化解情况',
trigger: ['blur'],
}"
>
<el-select
v-model="form.resolveSituation"
clearable
style="width: 280px"
placeholder="请选择信访化解情况"
>
<el-option
v-for="item in dict.resolveSituation"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
<template v-if="form.checkStatus !== InspectCase.UNABLE">
<div
v-if="
@ -233,7 +256,7 @@
type="danger"
plain
size="small"
@click="handleRemovePersonal(item)"
@click="handleRemoveBlame(item)"
text
class="ml-10"
>删除
@ -345,7 +368,7 @@
message: '请添加问题类型',
trigger: ['blur'],
}"
v-if="form.checkStatus !== InspectCase.FALSE"
v-if="problemIsTrue"
style="margin-bottom: 0"
>
<div
@ -482,9 +505,7 @@
message: '请选择责任类别',
trigger: ['blur'],
}"
v-if="
form.checkStatus !== InspectCase.FALSE
"
v-if="problemIsTrue"
>
<el-radio-group
v-model="item.responsibilityTypeCode"
@ -507,10 +528,7 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col
:span="12"
v-if="form.checkStatus !== InspectCase.FALSE"
>
<el-col :span="12" v-if="problemIsTrue">
<el-form-item
label="主观方面"
:prop="`blames.${index}.subjectiveAspectCode`"
@ -563,9 +581,7 @@
</div>
</el-form-item>
</el-col>
<template
v-if="form.checkStatus !== InspectCase.FALSE"
>
<template v-if="problemIsTrue">
<el-col :span="12">
<el-form-item
label="督察措施"
@ -633,10 +649,7 @@
</el-form-item>
</el-col>
</template>
<el-col
:span="12"
v-if="form.checkStatus !== InspectCase.FALSE"
>
<el-col :span="12" v-if="problemIsTrue">
<el-form-item
label="处理结果"
:prop="`blames.${index}.handleResultCode`"
@ -712,7 +725,7 @@
<el-button
type="primary"
plain
@click="handleAddPersonal"
@click="handleAddPersonalBlame"
>
<template #icon>
<icon name="el-icon-Plus" />
@ -857,9 +870,7 @@
message: '请选择责任类别',
trigger: ['blur'],
}"
v-if="
form.checkStatus !== InspectCase.FALSE
"
v-if="problemIsTrue"
>
<el-radio-group
v-model="
@ -885,10 +896,7 @@
</el-form-item>
</el-col>
<el-col
:span="12"
v-if="form.checkStatus !== InspectCase.FALSE"
>
<el-col :span="12" v-if="problemIsTrue">
<el-form-item
label="督察措施"
:prop="`blameLeaders.${index}.leadMeasuresCode`"
@ -923,10 +931,7 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col
:span="12"
v-if="form.checkStatus !== InspectCase.FALSE"
>
<el-col :span="12" v-if="problemIsTrue">
<el-form-item
label="维权容错"
:prop="`blameLeaders.${index}.leadProtectRightsCode`"
@ -961,9 +966,7 @@
message: '请选择处理结果',
trigger: ['blur'],
}"
v-if="
form.checkStatus !== InspectCase.FALSE
"
v-if="problemIsTrue"
>
<el-select
v-model="item.leadHandleResultCode"
@ -1106,10 +1109,7 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col
:span="12"
v-if="form.checkStatus !== InspectCase.FALSE"
>
<el-col :span="12" v-if="problemIsTrue">
<el-form-item
label="督察措施"
:prop="`blames.${index}.superviseMeasuresCode`"
@ -1161,7 +1161,7 @@
message: '请添加问题类型',
trigger: ['blur'],
}"
v-if="form.checkStatus !== InspectCase.FALSE"
v-if="problemIsTrue"
style="margin-bottom: 0"
>
<div
@ -1331,9 +1331,7 @@
message: '请选择责任类别',
trigger: ['blur'],
}"
v-if="
form.checkStatus !== InspectCase.FALSE
"
v-if="problemIsTrue"
>
<el-radio-group
v-model="item.responsibilityTypeCode"
@ -1365,9 +1363,7 @@
message: '请选择处理结果',
trigger: ['blur'],
}"
v-if="
form.checkStatus !== InspectCase.FALSE
"
v-if="problemIsTrue"
>
<el-select
v-model="item.handleResultCode"
@ -1426,9 +1422,14 @@
(police) => {
item.name = police.name;
item.idCode = police.idCode;
item.mobile = police.mobile;
}
"
/>
<el-input
placeholder="联系方式"
v-model="item.mobile"
/>
<el-button
plain
type="primary"
@ -1525,6 +1526,7 @@ import {
SubjectiveAspect,
} from "@/enums/dictEnums";
import useCatchStore from "@/stores/modules/catch";
import feedback from "@/utils/feedback";
const catchSotre = useCatchStore();
const dict = catchSotre.getDicts([
@ -1540,6 +1542,7 @@ const dict = catchSotre.getDicts([
"assistCase",
"accountabilityTarget",
"leadResponsibilityType",
"resolveSituation",
]);
const negative = inject("negative");
@ -1547,6 +1550,10 @@ const form = ref({
handlePolices: [{}],
});
const problemIsTrue = computed(() => {
return form.value.checkStatus !== InspectCase.FALSE;
});
getFormData();
watch(negative, () => {
@ -1564,7 +1571,9 @@ function getFormData() {
checkStatusDesc: negative.value.checkStatusDesc,
rectifyDesc: negative.value.rectifyDesc,
rectifyRestrictionDays: negative.value.rectifyRestrictionDays,
accountabilityTarget: "",
accountabilityTarget: negative.value.accountabilityTarget,
resolveSituation: negative.value.resolveSituation,
unrectifyReason: negative.value.unrectifyReason,
blames: negative.value.blames,
blameLeaders: negative.value.blameLeaders,
files: negative.value.files || [],
@ -1584,18 +1593,28 @@ function getFormData() {
console.log(form.value);
}
function handleAddPersonal() {
function handleAddBlame(type) {
form.value.blames.push({
type: BlameType.PERSONAL,
problems: [{}],
type,
problems:
negative.value.problems.length === 0
? [{}]
: negative.value.problems,
});
}
function handleAddDepartBlame() {
handleAddBlame(BlameType.DEPARTMENT);
}
function handleAddPersonalBlame() {
handleAddBlame(BlameType.PERSONAL);
if (form.value.blameLeaders.length == 0) {
handleAddBlameLeader();
}
}
function handleRemovePersonal(item) {
function handleRemoveBlame(item) {
form.value.blames.splice(form.value.blames.indexOf(item), 1);
}
@ -1626,18 +1645,18 @@ watch(
(item) => item.type === BlameType.PERSONAL
).length === 0
) {
handleAddPersonal();
handleAddPersonalBlame();
}
form.value.blames.forEach((item) => {
if (item.type === BlameType.DEPARTMENT) {
handleRemovePersonal(item);
handleRemoveBlame(item);
}
});
}
if (val === AccountabilityTarget.DEPARTMENT) {
form.value.blames.forEach((item) => {
if (item.type === BlameType.PERSONAL) {
handleRemovePersonal(item);
handleRemoveBlame(item);
}
});
if (
@ -1645,10 +1664,7 @@ watch(
(item) => item.type === BlameType.DEPARTMENT
).length === 0
) {
form.value.blames.push({
type: BlameType.DEPARTMENT,
problems: [{}],
});
handleAddDepartBlame();
}
form.value.blameLeaders = [];
}
@ -1658,17 +1674,14 @@ watch(
(item) => item.type === BlameType.PERSONAL
).length === 0
) {
handleAddPersonal();
handleAddPersonalBlame();
}
if (
form.value.blames.filter(
(item) => item.type === BlameType.DEPARTMENT
).length === 0
) {
form.value.blames.push({
type: BlameType.DEPARTMENT,
problems: [{}],
});
handleAddDepartBlame();
}
}
}
@ -1682,12 +1695,6 @@ function handleChangeCheckStatus(val, item) {
form.value.checkStatusName = dict.inspectCase.filter(
(item) => item.dictValue === val
)[0].dictLabel;
if (
form.value.accountabilityTarget !== AccountabilityTarget.DEPARTMENT &&
form.value.blames.length === 0
) {
handleAddPersonal();
}
}
function handleChangePolice(police, item) {
@ -1762,47 +1769,49 @@ function handleChangeDepartResultCode(item) {
}
function validateHandlePolices(rule, value, cb) {
console.log(value);
if (value.length === 0) {
cb(new Error("请选择经办人"));
} else if (!value[0].name) {
cb(new Error("请选择经办人"));
} else if (!value[0].mobile) {
cb(new Error("请输入经办人联系方式"));
} else {
cb();
cb()
}
}
const formRef = ref(null);
async function validate() {
debugger;
//
if (form.value.accountabilityTarget === AccountabilityTarget.PERSONAL) {
form.value.blames = form.value.blames.filter(
(item) => item.type === BlameType.PERSONAL
);
}
const flag = await formRef.value.validate();
if (flag) {
if (
form.value.accountabilityTarget !== AccountabilityTarget.DEPARTMENT
) {
let arr = [];
form.value.blameLeaders.forEach((item) => {
arr = arr.concat(item.blameIdCodes);
});
const blame = form.value.blames.filter(
(item) =>
item.type === BlameType.PERSONAL &&
!arr.includes(item.blameIdCode)
await formRef.value.validate();
if (form.value.accountabilityTarget !== AccountabilityTarget.DEPARTMENT) {
let arr = [];
form.value.blameLeaders.forEach((item) => {
arr = arr.concat(item.blameIdCodes);
});
const blame = form.value.blames.filter(
(item) =>
item.type === BlameType.PERSONAL &&
!arr.includes(item.blameIdCode)
);
if (blame.length) {
throw new Error(
`涉及人员【${blame
.map((item) => item.blameName)
.join("、")}未关联领导`
);
if (blame.length) {
throw new Error(
`涉及人员【${blame
.map((item) => item.blameName)
.join("、")}未关联领导`
);
}
}
return form.value;
}
return form.value;
}
function getData() {

2
src/components/negativeInfo/police-dialog.vue

@ -216,7 +216,7 @@
/>
</el-col>
<el-col :span="8">
<h5>问题类型占比</h5>
<h5>问题涉及方面分布</h5>
<v-charts
style="height: 320px"
:option="problemTypePieOptions"

216
src/components/police-picker.vue

@ -0,0 +1,216 @@
<template>
<div class="flex gap">
<el-tag type="info" effect="plain" closable v-for="item in modelValue" :key="item">{{ item.name }}</el-tag>
<el-button size="small" type="primary" plain @click="show = true">
<template #icon>
<icon name="el-icon-Plus" />
</template>
</el-button>
</div>
<el-dialog title="选择警员" v-model="show" width="60vw" top="5vh">
<div style="min-height: 70vh">
<el-row :gutter="20">
<el-col :span="6">
<el-scrollbar max-height="70vh">
<el-tree
:data="treeData"
:props="{ label: 'shortName', value: 'id' }"
:default-expanded-keys="['12630']"
@node-click="handleSelectDepart"
/>
</el-scrollbar>
</el-col>
<el-col :span="18">
<header class="flex between mb-20">
<div class="flex gap">
<el-input
placeholder="警员姓名"
v-model="query.name"
clearable
style="width: 220px"
/>
<el-input
placeholder="请输入"
v-model="query.empNo"
clearable
style="width: 220px"
/>
<el-input
placeholder="身份证号码"
v-model="query.idCode"
clearable
style="width: 220px"
/>
</div>
<el-button type="primary">查询</el-button>
</header>
<div class="table-container">
<el-table
:data="polices"
row-key="id"
max-height="890px"
@selection-change="selectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column
label="姓名"
prop="name"
width="90"
/>
<el-table-column
label="警号"
prop="empNo"
width="100"
show-overflow-tooltip
/>
<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>
</div>
</template>
</el-table-column>
<el-table-column
label="人员属性"
width="120"
align="center"
>
<template #default="{ row }">
<span>{{
getDictLable(
dict.personType,
row.personType
)
}}</span>
</template>
</el-table-column>
<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>
</template>
</el-table-column>
<el-table-column
label="身份证"
prop="idCode"
width="200"
/>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
<div class="flex gap mt-10 wrap v-center">
<span>已选警员</span>
<el-tag
v-for="item in checkPolices"
:key="item"
closable
>{{ item.name }}</el-tag
>
</div>
</el-col>
</el-row>
</div>
<footer class="flex end">
<el-button @click="show = false">取消</el-button>
<el-button type="primary" @click="submit">确定</el-button>
</footer>
</el-dialog>
</template>
<script setup>
import { departTreeList } from "@/api/system/depart";
import { listPolice } from "@/api/system/police";
import useCatchStore from "@/stores/modules/catch";
import { getDictLable } from "@/utils/util";
const catchSotre = useCatchStore();
const dict = catchSotre.getDicts(["personType"]);
const props = defineProps({
modelValue: {
type: Array,
default: []
}
});
const emit = defineEmits(['update:modelValue'])
const show = ref(false);
const query = ref({
departBranch: true,
});
const total = ref(0);
const treeData = catchSotre.getDepartsAll();
const polices = ref([]);
function getList() {
listPolice(query.value).then((data) => {
polices.value = data.records;
total.value = data.total;
});
}
const checkPolices = ref([]);
function selectionChange(selectionRows) {
checkPolices.value = selectionRows.map(item => {
return {
name: item.name,
empNo: item.empNo,
idCode: item.idCode
}
});
}
function handleSelectDepart(node) {
query.value.departId = node.id;
getList();
}
function submit() {
emit('update:modelValue', checkPolices.value)
show.value = false
}
onMounted(() => {
getList();
});
</script>
<style lang="scss">
.el-tree-node.is-current > .el-tree-node__content {
background-color: #e8e9f3;
}
</style>

2
src/layout/components/Header.vue

@ -35,7 +35,7 @@
</ul>
<div class="overlay" v-if="supportShow" @click="supportShow = false">
<div class="position-center support-box">
<div class="position-center support-box" @click.stop>
<header class="flex">
<span>技术支持</span>
<img src="/imgs/support.png" alt="" />

2
src/utils/util.ts

@ -319,7 +319,7 @@ export function getFileType(fileName) {
if (fileName.endsWith('.pdf')) {
return FileType.PDF;
}
if (fileName.endsWith('.jpg') || fileName.endsWith('.png') || fileName.endsWith('.gif')) {
if (fileName.endsWith('.jpg') || fileName.endsWith('.png') || fileName.endsWith('.gif') || fileName.endsWith('.jpeg')) {
return FileType.IMG;
}
if (fileName.endsWith('.doc') || fileName.endsWith('.docx')) {

2
src/views/books/Ajhc.vue

@ -116,7 +116,7 @@
prop="thingDesc"
show-overflow-tooltip
/>
<el-table-column label="操作" width="200">
<el-table-column label="操作" width="120">
<template #default="{ row }">
<el-button
type="primary"

4
src/views/books/Gabxf.vue

@ -125,12 +125,12 @@
width="160"
/>
<el-table-column
label="投诉人"
label="信访人"
prop="responderName"
width="90"
/>
<el-table-column
label="投诉人电话"
label="信访人电话"
prop="responderPhone"
width="120"
/>

6
src/views/books/Gjxf.vue

@ -128,12 +128,12 @@
width="160"
/>
<el-table-column
label="投诉人"
label="信访人"
prop="responderName"
width="90"
/>
<el-table-column
label="投诉人电话"
label="信访人电话"
prop="responderPhone"
width="120"
/>
@ -229,7 +229,7 @@
link
@click="handleAction(row)"
v-if="row.id"
>详情</el-button
>问题详情</el-button
>
</template>
</el-table-column>

89
src/views/data/Ajhc.vue

@ -131,9 +131,9 @@
width="90"
/>
<el-table-column
label="投诉人电话"
label="投诉人联系方式"
prop="responderPhone"
width="120"
width="130"
/>
<el-table-column label="业务类别" prop="businessTypeName" />
<el-table-column label="涉嫌问题" prop="involveProblem" />
@ -164,9 +164,9 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<el-table-column label="操作" width="240">
<template #default="{ row }">
<el-button type="primary" link @click="handleDetail(row)" v-if="row.distributionState === '1'"
<el-button type="primary" link @click="handleAction(row)" v-if="row.distributionState === '1'"
>问题详情
</el-button>
<template
@ -194,7 +194,12 @@
>移除
</el-button>
</template>
<el-button
type="primary"
link
@click="handleDetail(row)"
>详情</el-button
>
<el-button type="danger" link @click="handleDel(row)"
>删除
</el-button>
@ -359,6 +364,66 @@
:id="activeNegativeId"
@close="negativeShow = false"
/>
<el-dialog title="案件核查详情" v-model="detailShow" width="60vw">
<div style="min-height: 50vh">
<div class="row" style="margin: 0 60px">
<div class="col col-12">
<label>案件编号</label>
<span>{{ activeRow.originId }}</span>
</div>
<div class="col col-12">
<label>受理时间</label>
<span>{{ activeRow.discoveryTime }}</span>
</div>
<div class="col col-12">
<label>问题发生时间</label>
<span>{{ activeRow.happenTime }}</span>
</div>
<div class="col col-12">
<label>问题来源</label>
<span>{{ activeRow.problemSources }}</span>
</div>
<div class="col col-12">
<label>投诉人</label>
<span>{{ activeRow.responderName || '/' }}</span>
</div>
<div class="col col-12">
<label>投诉人联系方式</label>
<span>{{ activeRow.responderPhone || '/' }}</span>
</div>
<div class="col col-12">
<label>业务类别</label>
<span>{{ activeRow.businessTypeName }}</span>
</div>
<div class="col col-12">
<label>涉嫌问题</label>
<span>{{ activeRow.involveProblem }}</span>
</div>
<div class="col col-12">
<label>涉及单位</label>
<span
><span>{{ activeRow.secondDepartName }}</span>
<span>{{ activeRow.thirdDepartName }}</span></span
>
</div>
<div class="col col-12">
<label>是否属实</label>
<span
><span v-if="activeRow.isReal === 1">属实</span>
<span v-else-if="activeRow.isReal === 2">部分属实</span>
<span v-else-if="activeRow.isReal === 3">不属实</span>
<span v-else>/</span></span
>
</div>
<div class="col col-24">
<label>具体内容</label>
<span class="content">{{ activeRow.thingDesc }}</span>
</div>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
@ -454,10 +519,16 @@ async function handleSubmit() {
const negativeShow = ref(false)
const activeNegativeId = ref('')
async function handleDetail(row) {
async function handleAction(row) {
activeNegativeId.value = await getNegativeId(row.originId)
negativeShow.value = true
}
</script>
<style lang="scss" scoped>
</style>
const detailShow = ref(false);
const activeRow = ref({});
function handleDetail(row) {
activeRow.value = row;
detailShow.value = true;
}
</script>

137
src/views/data/Gabxf.vue

@ -27,7 +27,7 @@
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="投诉人">
<el-form-item label="信访人">
<div class="flex gap">
<el-select
v-model="query.responderKey"
@ -125,24 +125,32 @@
label="投诉渠道"
prop="channelForFilingComplaints"
/>
<el-table-column
label="信访方式"
prop="petitionType"
/>
<el-table-column
label="登记时间"
prop="discoveryTime"
show-overflow-tooltip
/>
<el-table-column
label="投诉人"
label="信访人"
prop="responderName"
width="90"
/>
<el-table-column label="电话" prop="responderPhone" />
<el-table-column
label="初重信访"
prop="initialPetition"
align="center"
width="90"
/>
<el-table-column label="身份证号码" prop="responderIdCode" />
<el-table-column label="初重信访" align="center" width="85">
<template #default="{ row }">
<span>{{
getDictLable(
dict.initialPetition,
row.initialPetition
)
}}</span>
</template>
</el-table-column>
<el-table-column label="缠访闹访" width="85" align="center">
<template #default="{ row }">
<span v-if="row.entanglementVisits === true"></span>
@ -179,7 +187,12 @@
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<el-table-column
label="办理情况"
prop="petitionProcessingStatus"
width="100"
/>
<el-table-column label="操作" width="240">
<template #default="{ row }">
<template
v-if="
@ -211,8 +224,14 @@
type="primary"
link
@click="handleAction(row)"
>处理详情
>问题详情
</el-button>
<el-button
type="primary"
link
@click="handleDetail(row)"
>详情</el-button
>
<el-button type="danger" link @click="handleDel(row)"
>删除</el-button
>
@ -251,6 +270,93 @@
:id="activeNegativeId"
@close="negativeShow = false"
/>
<el-dialog title="详情" v-model="detailShow" width="60vw">
<div style="min-height: 50vh">
<div class="row" style="margin: 0 60px">
<div class="col col-12">
<label>信件编号</label>
<span>{{ activeRow.originId }}</span>
</div>
<div class="col col-12">
<label>投诉渠道</label>
<span>{{
activeRow.channelForFilingComplaints || "/"
}}</span>
</div>
<div class="col col-12">
<label>信访方式</label>
<span>{{
activeRow.petitionType || "/"
}}</span>
</div>
<div class="col col-12">
<label>登记时间</label>
<span>{{ activeRow.discoveryTime }}</span>
</div>
<div class="col col-12">
<label>信访人</label>
<span>{{ activeRow.responderName }}</span>
</div>
<div class="col col-12">
<label>信访人联系方式</label>
<span>{{ activeRow.responderPhone }}</span>
</div>
<div class="col col-12">
<label>信访人身份证</label>
<span>{{ activeRow.responderIdCode || '/' }}</span>
</div>
<div class="col col-12">
<label>初重信访</label>
<span>{{
getDictLable(
dict.initialPetition,
activeRow.initialPetition
) || "/"
}}</span>
</div>
<div class="col col-12">
<label>缠访闹访</label>
<span
><span v-if="activeRow.entanglementVisits === true"
></span
>
<span v-else-if="activeRow.entanglementVisits === false"
></span
>
<span v-else
>/</span
>
</span
>
</div>
<div class="col col-12">
<label>群众集访</label>
<span
><span v-if="activeRow.massVisits === true"></span>
<span v-else-if="activeRow.massVisits === false"
></span
>
<span v-else
>/</span
>
</span
>
</div>
<div class="col col-12">
<label>被投诉机构</label>
<span
><span>{{ activeRow.secondDepartName }}</span>
<span>{{ activeRow.thirdDepartName }}</span></span
>
</div>
<div class="col col-24">
<label>具体内容</label>
<span class="content">{{ activeRow.thingDesc }}</span>
</div>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
@ -332,9 +438,16 @@ function handleAction(row) {
}
function handleShowImport() {
console.log('handleShowImport')
show.value = true
}
const detailShow = ref(false);
const activeRow = ref({});
function handleDetail(row) {
activeRow.value = row;
detailShow.value = true;
}
</script>
<style lang="scss" scoped>
</style>

164
src/views/data/Gjxf.vue

@ -3,7 +3,6 @@
<header>
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="登记时间">
<date-time-range-picker-ext
@ -27,7 +26,7 @@
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="投诉人">
<el-form-item label="信访人">
<div class="flex gap">
<el-select
v-model="query.responderKey"
@ -55,24 +54,22 @@
</el-col>
<el-col :span="6">
<el-form-item label="被投诉机构">
<depart-tree-select
v-model="query.departId"
/>
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="初重信访">
<el-select
clearable
v-model="query.initialPetition"
>
<el-option
v-for="item in dict.initialPetition"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
clearable
v-model="query.initialPetition"
>
<el-option
v-for="item in dict.initialPetition"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
@ -125,18 +122,23 @@
label="投诉渠道"
prop="channelForFilingComplaints"
/>
<el-table-column
label="信访方式"
prop="petitionType"
/>
<el-table-column
label="登记时间"
prop="discoveryTime"
show-overflow-tooltip
/>
<el-table-column
label="投诉人"
label="信访人"
prop="responderName"
width="90"
/>
<el-table-column label="电话" prop="responderPhone" />
<el-table-column label="身份证号码" prop="responderIdCode" />
<el-table-column label="初重信访" align="center" width="85">
<template #default="{ row }">
<span>{{
@ -170,6 +172,11 @@
prop="thingDesc"
show-overflow-tooltip
/>
<el-table-column
label="办理情况"
prop="petitionProcessingStatus"
width="100"
/>
<el-table-column label="状态">
<template #default="{ row }">
<el-tag>{{
@ -180,7 +187,7 @@
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<el-table-column label="操作" width="240">
<template #default="{ row }">
<template
v-if="
@ -208,12 +215,20 @@
>
</template>
<el-button
v-if="row.negativeId && row.distributionState === '1'"
v-if="
row.negativeId && row.distributionState === '1'
"
type="primary"
link
@click="handleAction(row)"
>处理详情
>问题详情
</el-button>
<el-button
type="primary"
link
@click="handleDetail(row)"
>详情</el-button
>
<el-button type="danger" link @click="handleDel(row)"
>删除</el-button
>
@ -235,11 +250,7 @@
</div>
</div>
<data-gj-import
v-model="show"
@close="show = false"
@update="getList"
/>
<data-gj-import v-model="show" @close="show = false" @update="getList" />
<data-distrbute
v-model:show="distributeShow"
@ -252,6 +263,101 @@
:id="activeNegativeId"
@close="negativeShow = false"
/>
<el-dialog title="详情" v-model="detailShow" width="60vw" :lock-scroll="false">
<div style="min-height: 50vh">
<div class="row" style="margin: 0 60px">
<div class="col col-12">
<label>信件编号</label>
<span>{{ activeRow.originId }}</span>
</div>
<div class="col col-12">
<label>投诉渠道</label>
<span>{{
activeRow.channelForFilingComplaints || "/"
}}</span>
</div>
<div class="col col-12">
<label>信访方式</label>
<span>{{
activeRow.petitionType || "/"
}}</span>
</div>
<div class="col col-12">
<label>登记时间</label>
<span>{{ activeRow.discoveryTime }}</span>
</div>
<div class="col col-12">
<label>信访人</label>
<span>{{ activeRow.responderName }}</span>
</div>
<div class="col col-12">
<label>信访人联系方式</label>
<span>{{ activeRow.responderPhone }}</span>
</div>
<div class="col col-12">
<label>信访人身份证号码</label>
<span>{{ activeRow.responderIdCode || '/' }}</span>
</div>
<div class="col col-12">
<label>初重信访</label>
<span>{{
getDictLable(
dict.initialPetition,
activeRow.initialPetition
) || "/"
}}</span>
</div>
<div class="col col-12">
<label>缠访闹访</label>
<span
><span v-if="activeRow.entanglementVisits === true"
></span
>
<span v-else-if="activeRow.entanglementVisits === false"
></span
>
<span v-else
>/</span
>
</span
>
</div>
<div class="col col-12">
<label>群众集访</label>
<span
><span v-if="activeRow.massVisits === true"></span>
<span v-else-if="activeRow.massVisits === false"
></span
>
<span v-else
>/</span
>
</span
>
</div>
<div class="col col-12">
<label>被投诉机构</label>
<span
><span>{{ activeRow.secondDepartName }}</span>
<span>{{ activeRow.thirdDepartName }}</span></span
>
</div>
<div class="col col-12">
<label>办理情况</label>
<span>{{ activeRow.petitionProcessingStatus || '/' }}</span>
</div>
<div class="col col-12">
<label>化解情况</label>
<span>{{ '/' }}</span>
</div>
<div class="col col-24">
<label>具体内容</label>
<span class="content">{{ activeRow.thingDesc }}</span>
</div>
</div>
</div>
</el-dialog>
</template>
<script setup>
import {
@ -323,6 +429,14 @@ function handleAction(row) {
negativeShow.value = true;
activeNegativeId.value = row.negativeId;
}
const detailShow = ref(false);
const activeRow = ref({});
function handleDetail(row) {
activeRow.value = row;
detailShow.value = true;
}
</script>
<style lang="scss" scoped>
</style>

87
src/views/data/Mail12337.vue

@ -130,8 +130,15 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button type="primary" link @click="handleAction(row)" v-if="row.distributionState === '1'">问题详情</el-button>
<el-button
type="primary"
link
@click="handleDetail(row)"
>详情</el-button
>
<el-button type="danger" link @click="handleDel(row)"
>删除
</el-button>
@ -203,7 +210,9 @@
</div>
</template>
</el-upload>
<div class="mt-10">说明请上传12337信访投诉台账表格进行导入操作上传成功后点击下一步进行数据核验</div>
<div class="mt-10">
说明请上传12337信访投诉台账表格进行导入操作上传成功后点击下一步进行数据核验
</div>
</div>
</template>
<template v-if="activeStep === 1">
@ -384,7 +393,9 @@
/>
</el-table>
</div>
<div class="mt-10">说明数据校验展示信访投诉关键信息标红内容为必填项</div>
<div class="mt-10">
说明数据校验展示信访投诉关键信息标红内容为必填项
</div>
<div class="text-danger text-wrap mt-10 text-small">
{{ errMsg }}
</div>
@ -548,10 +559,57 @@
>
</footer>
</el-dialog>
<negative-dialog
v-model="negativeDetailShow"
:id="activeNegativeId"
@close="negativeDetailShow = false"
/>
<el-dialog title="详情" v-model="detailShow" width="60vw">
<div style="min-height: 50vh">
<div class="row" style="margin: 0 60px">
<div class="col col-12">
<label>信件编号</label>
<span>{{ activeRow.onlyId }}</span>
</div>
<div class="col col-12">
<label>投诉渠道</label>
<span>{{
activeRow.letterSource || "/"
}}</span>
</div>
<div class="col col-12">
<label>登记时间</label>
<span>{{ activeRow.discoverTime }}</span>
</div>
<div class="col col-12">
<label>投诉人</label>
<span>{{ activeRow.name }}</span>
</div>
<div class="col col-12">
<label>投诉人联系方式</label>
<span>{{ activeRow.phone }}</span>
</div>
<div class="col col-12">
<label>被投诉机构</label>
<span
><span>{{ activeRow.secondDepartName }}</span>
<span>{{ activeRow.thirdDepartName }}</span></span
>
</div>
<div class="col col-24">
<label>具体内容</label>
<span class="content">{{ activeRow.wjwfProject }}</span>
</div>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { delPetitionComplaint } from "@/api/data/petitionComplaint";
import { getIdByOriginId } from "@/api/work/negative";
import { ProblemSources, DistributionState } from "@/enums/dictEnums";
import feedback from "@/utils/feedback";
@ -579,7 +637,7 @@ const router = useRouter();
const query = ref({
size: 10,
current: 1,
responderValue: 'name'
responderValue: "name",
});
const list = ref([]);
@ -596,7 +654,7 @@ function reset() {
query.value = {
size: 10,
current: 1,
responderValue: 'name'
responderValue: "name",
};
getList();
}
@ -714,6 +772,19 @@ watch(importShow, (val) => {
fileList.value = [];
}
});
</script>
<style lang="scss" scoped>
</style>
const activeNegativeId = ref('')
const negativeDetailShow = ref(false)
async function handleAction(row) {
activeNegativeId.value = await getIdByOriginId(row.onlyId);
negativeDetailShow.value = true;
}
const detailShow = ref(false);
const activeRow = ref({});
function handleDetail(row) {
activeRow.value = row;
detailShow.value = true;
}
</script>

2
src/views/data/Mailbox.vue

@ -119,7 +119,7 @@
type="primary"
link
@click="handleAction(row)"
>详情</el-button
>问题详情</el-button
>
</template>
</el-table-column>

5
src/views/data/VideoInspection.vue

@ -472,6 +472,7 @@
v-model="manualShow"
width="80vw"
top="5vh"
:lock-scroll="false"
>
<div style="min-height: 500px">
<div class="table-container">
@ -479,7 +480,7 @@
<el-table-column
label="预警级别"
prop="alarmLevel"
width="100"
width="90"
align="center"
>
<template #default="{ row }">
@ -491,7 +492,7 @@
<el-table-column label="预警类别" prop="systemKeyName" />
<el-table-column label="预警时间" prop="rqsj" />
<el-table-column label="案事件名称" prop="title" />
<el-table-column label="发生单位名称" prop="fsdwGajgmc" />
<el-table-column label="发生单位名称" prop="fsdwGajgmc" show-overflow-tooltip />
<el-table-column label="操作" width="140">
<template #default="{ row }">
<el-button

1224
src/views/datav/Global.vue

File diff suppressed because it is too large Load Diff

6
src/views/datav/Jwpy.vue

@ -431,7 +431,7 @@ const handleChartClick = async (params) => {
//
const discovery = async () => {
//
await GetZHMYLPM(selectYear.value, selectMonth.value, selectOrg.value, task.value, 1).then((res) => {
await GetZHMYLPM(selectYear.value, selectMonth.value, selectOrg.value, task.value, selectOrg.value === '4301' ? 1 : 2).then((res) => {
tableData1.value = res[0].lstCity
let temp = res[0].lstSheng;
//
@ -751,9 +751,9 @@ async function getData() {
temp = temp.filter(item => item.Name !== null);
tableData.value = temp
});
console.log('selectOrg', selectOrg.value)
//
GetZHMYLPM(selectYear.value, selectMonth.value, selectOrg.value, task.value, 2).then((res) => {
GetZHMYLPM(selectYear.value, selectMonth.value, selectOrg.value, task.value, selectOrg.value === '4301' ? 1 : 2).then((res) => {
tableData1.value = res[0].lstCity
let temp = res[0].lstSheng;
//

2
src/views/datav/MailVisits.vue

@ -1001,7 +1001,7 @@ const fxsjEntanglementAnimation = () => {
fxsjEntanglementTab.value = (parseInt(fxsjEntanglementTab.value) % 3 + 1).toString();
};
fxsjEntanglementIntervalId = setInterval(fxsjEntanglementAnimation, 3000);
// //
// //
// const wtlxzbCircularAnimation = () => {
// const wtlxzbOptionTemp = wtlxzbOption?.value?.chart;
// if (!wtlxzbOptionTemp) return;

15
src/views/datav/RightsComfort.vue

@ -423,6 +423,9 @@ const getRightsRankList = async (timeValue) => {
const getComfortOverview = async (timeValue) => {
const res = await getALlComfortCount(timeValue);
comfortOverview.value = res.comfortOverview;
// comfortOverview.value.comfortCaseTotal = 136;
// comfortOverview.value.hurtTotal = 112;
// comfortOverview.value.hitTotal = 167;
}
//
const getMapData = async (timeValue) => {
@ -486,12 +489,12 @@ const getMapData = async (timeValue) => {
//
const getPunishmentSituationList = async (timeValue) => {
const res = await getPunishmentSituation(timeValue);
punishmentSituationOption.series[0].data = res.punishmentSituationList;
// punishmentSituationOption.series[0].data = res.punishmentSituationList;
}
//
const getComfortSituationList = async (timeValue) => {
const res = await getComfortSituation(timeValue);
comfortSituationOption.series[0].data = res.comfortSituationList;
// comfortSituationOption.series[0].data = res.comfortSituationList;
}
// -
@ -668,8 +671,8 @@ const punishmentSituationOption = {
color: "#fff",
},
data: [
// {value: 71, name: ""},
// {value: 97, name: ""},
{value: 91, name: "刑事追究"},
{value: 78, name: "行政处理"},
],
},
],
@ -686,8 +689,8 @@ const comfortSituationOption = {
color: "#fff",
},
data: [
// {value: 71, name: ""},
// {value: 97, name: ""},
{value: 30, name: "民警"},
{value: 52, name: "辅警"},
],
},
],

6
src/views/datav/SceneInsp.vue

@ -170,7 +170,7 @@
</datav-tabs>
</datav-card>
<datav-card title="问题类型占比">
<datav-card title="问题涉及方面分布">
<v-charts
style="height: 310px"
:option="wtlxPieOption"
@ -528,7 +528,7 @@ const fxsjRankOverview = ref({}); // 日常督察总览分县市局
const jsdwRankOverview = ref({}); //
const fxsjChangedRankList = ref([]); //
const jsdwChangedRankList = ref([]); //
const wtlxList = ref([]); //
const wtlxList = ref([]); //
const fxsjYellowBetOverview = ref({
proTotal: 0,
@ -873,7 +873,7 @@ const sceneInspRcdxRankAnimation = () => {
).toString();
};
sceneInspRcdxIntervalId = setInterval(sceneInspRcdxRankAnimation, 3000);
//
//
const sceneProblemTypeRateAnimation = () => {
const temp = sceneProblemTypeRate?.value?.chart;
if (!temp) return;

128
src/views/datav/VideoInsp.vue

@ -21,7 +21,10 @@
</div>
</div>
<div class="mb-12">
<VideoPlay :url="activeUrl" :showOperateBtns="false" />
<VideoPlay
:url="activeUrl"
:showOperateBtns="false"
/>
</div>
<el-scrollbar max-width="100%">
<div class="flex gap" style="width: 840px">
@ -143,54 +146,30 @@
<el-col :span="6">
<datav-card title="实时预警">
<el-scrollbar height="450px">
<div class="message message-error">
<div class="message-title">待处理</div>
<div>
芙蓉-定王台-办案区-问室
湖南省长沙市公安局芙蓉分局定王台派出所
&emsp; 民警单人询的违规问题
</div>
<div class="message-footer flex between">
<span>芙蓉分局定王台派出所</span>
<span>2024-11-18 20:12</span>
</div>
</div>
<div class="message message-info">
<div class="message-title">待处理</div>
<div>
望城-管理中心-办案区-询问室湖南省长沙市望城区公安局法制大队&emsp;
民警单人询的违规问题
</div>
<div class="message-footer flex between">
<span>望城区公安局法制大队</span>
<span>2024-11-18 19:12</span>
</div>
</div>
<div class="message">
<div class="message-title">待处理</div>
<div>
执法办案中心-询问室7湖南省长沙市公安局芙蓉分局蓉园派出所
&emsp;同时讯问多名嫌疑对象
</div>
<div class="message-footer flex between">
<span>芙蓉分局蓉园派出所</span>
<span>2024-11-18 16:12</span>
</div>
</div>
<div class="message">
<div class="message-title">待处理</div>
<div>
开福-直属-执法办案管理-讯询问室湖南省长沙市公安局开福分局法制大队
&emsp;民警单人询的违规问题
<div
class="message message-info pointer"
v-for="item in videoInspections"
:key="item"
:active="item.distributionState === '1'"
@click="handleOpenData"
>
<div class="message-title">
{{
item.distributionState === "1"
? "已处理"
: "待处理"
}}
</div>
<div>{{ item.title }}</div>
<div>{{ item.content }}</div>
<div class="message-footer flex between">
<span>开福分局法制大队</span>
<span>2024-11-18 15:12</span>
<span>{{ item.fsdwGajgmc }}</span>
<span>{{ item.rqsj }}</span>
</div>
</div>
</el-scrollbar>
</datav-card>
<datav-card title="问题类型占比">
<datav-card title="问题涉及方面分布">
<v-charts
style="height: 300px"
:option="ProblemTypeRateChart"
@ -219,6 +198,7 @@ import {
getVideoSuperviseTrend,
getVideoStatus,
} from "@/api/screen/videoSupervise.ts";
import { listVideoInspection } from "@/api/data/videoInspection";
import moment from "moment/moment.js";
import { mapOrgNameMapping } from "@/enums/orgMapping.js";
import { onMounted } from "vue";
@ -465,7 +445,7 @@ const ProblemTypeRateChart = ref({
tooltip: {
trigger: "item",
},
}); //
}); //
// endregion
// region
@ -573,7 +553,7 @@ const videoTrendAnimation = () => {
});
};
videoTrendIntervalId = setInterval(videoTrendAnimation, 2000);
//
//
const videoProblemTypeRateAnimation = () => {
const temp = videoProblemTypeRate?.value?.chart;
if (!temp) return;
@ -694,9 +674,9 @@ const videoProblemTypeRateAnimationStop = () => {
});
};
import { listVideoConfigByDepartId } from '@/api/system/videoConfig'
import { listVideoConfigByDepartId } from "@/api/system/videoConfig";
const videos = ref([]);
const activeUrl = ref('');
const activeUrl = ref("");
const videoStatus = ref({
all: 0,
@ -707,12 +687,12 @@ onMounted(() => {
getVideoStatus().then((data) => {
videoStatus.value = data;
});
listVideoConfigByDepartId('12630').then(data => {
listVideoConfigByDepartId("12630").then((data) => {
videos.value = data;
if (data.length > 0) {
activeUrl.value = data[0].videoUrl
activeUrl.value = data[0].videoUrl;
}
})
});
});
const activeVideoIndex = ref(0);
@ -721,6 +701,23 @@ function handlePlay(item, index) {
activeUrl.value = item.videoUrl;
}
const videoInspections = ref([]);
async function getVideoInspection() {
const data = await listVideoInspection({
current: 1,
size: 5,
});
videoInspections.value = data.records;
}
onMounted(() => {
getVideoInspection();
});
function handleOpenData() {
window.open(router.resolve('/data/VideoInspection').href)
}
</script>
<style lang="scss" scoped>
@ -746,37 +743,21 @@ img {
margin-bottom: 10px;
background: linear-gradient(
180deg,
rgba(145, 145, 145, 0) 0%,
rgba(164, 164, 164, 0.26) 98%
rgba(208, 18, 18, 0) 0%,
rgba(255, 0, 0, 0.26) 100%
);
border: 1px solid;
border-image: linear-gradient(
180deg,
rgba(255, 255, 255, 0.28),
rgba(255, 255, 255, 0.26)
rgba(255, 71, 71, 0.59),
rgba(251, 95, 95, 1)
)
1 1;
&.message-error {
background: linear-gradient(
180deg,
rgba(208, 18, 18, 0) 0%,
rgba(255, 0, 0, 0.26) 100%
);
border: 1px solid;
border-image: linear-gradient(
180deg,
rgba(255, 71, 71, 0.59),
rgba(251, 95, 95, 1)
)
1 1;
.message-title {
color: #ff0017;
}
.message-title {
color: #ff0017;
}
&.message-info {
&[active="true"] {
background: linear-gradient(
180deg,
rgba(18, 104, 208, 0) 0%,
@ -799,7 +780,6 @@ img {
font-size: 23px;
font-weight: 700;
margin-bottom: 10px;
color: #597ae9;
}
.message-footer {

20
src/views/datav/subonedatav/SubOneGlobal.vue

@ -55,7 +55,7 @@
/>
<datav-statistic
:value="overview.supervisionPro"
title="督问题"
title="督导检查问题"
style="width: 13.66%; margin-left: 30px"
/>
<datav-statistic
@ -124,7 +124,7 @@
</el-scrollbar>
</datav-card>
<datav-card title="问题类型占比">
<datav-card title="问题涉及方面分布">
<v-charts
style="height: 370px;"
:option="wtlxPieOption"
@ -171,7 +171,7 @@ const currentDepartId = route.query.departId;
const fxsjlist = ref([]); //
const jsdwlist = ref([]); //
const ywzblist = ref([]); //
const wtlxlist = ref([]); //
const wtlxlist = ref([]); //
const tcwtlist = ref([]); //
const overview = ref({
totalPro: 0,
@ -214,7 +214,7 @@ let subOneCardIntervalId;
let subOneYwlxPieCircularIntervalId; //
let subOneGlobalMapIntervalId; //
let subOneGlobalTrendIntervalId; //
let subOneWtlxPieCircularIntervalId; //
let subOneWtlxPieCircularIntervalId; //
// endregion
// region
@ -234,7 +234,7 @@ const ywlxPieOption = ref({
trigger: "item",
},
});
//
//
const wtlxPieOption = computed(() => {
return {
tooltip: {
@ -269,11 +269,11 @@ const option = ref({
<div class="tooltip-content">
<ul class="tooltip-ul" >
<li>问题总数 <span>${dataItem.totalPro}</span></li>
<li>问题 <span>${dataItem.supervisePro}</span></li>
<li>导检查问题 <span>${dataItem.supervisePro}</span></li>
<li>案件核查问题 <span>${dataItem.caseVerifyPro}</span></li>
<li>信访投诉问题 <span>${dataItem.mailPro}</span></li>
<li>民意感知问题 <span>${dataItem.policePro}</span></li>
<li>审计督问题 <span>${dataItem.reviewPro}</span></li>
<li>审计督问题 <span>${dataItem.reviewPro}</span></li>
</ul>
</div>
</div>
@ -285,11 +285,11 @@ const option = ref({
<div class="tooltip-content">
<ul class="tooltip-ul"">
<li>问题总数 <span>-</span></li>
<li>问题 <span>-</span></li>
<li>导检查问题 <span>-</span></li>
<li>案件核查问题 <span>-</span></li>
<li>信访投诉问题 <span>-</span></li>
<li>民意感知问题 <span>-</span></li>
<li>审计督问题 <span>-</span></li>
<li>审计督问题 <span>-</span></li>
</ul>
</div>
</div>
@ -547,7 +547,7 @@ const subOneGlobalTrendAnimation = () => {
}
subOneGlobalTrendIntervalId = setInterval(subOneGlobalTrendAnimation, 2000);
//
//
const subOneWtlxzbCircularAnimation = () => {
const wtlxzbOptionTemp = subOneWtlxzbOption?.value?.chart;
if (!wtlxzbOptionTemp) return;

2
src/views/datav/subonedatav/SubOneMailVisits.vue

@ -992,7 +992,7 @@ const subOneFxsjEntanglementAnimation = () => {
subOneFxsjEntanglementTab.value = (parseInt(subOneFxsjEntanglementTab.value) % 3 + 1).toString();
};
subOneFxsjEntanglementIntervalId = setInterval(subOneFxsjEntanglementAnimation, 3000);
// //
// //
// const wtlxzbCircularAnimation = () => {
// const wtlxzbOptionTemp = wtlxzbOption?.value?.chart;
// if (!wtlxzbOptionTemp) return;

6
src/views/datav/subonedatav/SubOneSceneInsp.vue

@ -126,7 +126,7 @@
</datav-card>
<datav-card title="问题类型占比">
<datav-card title="问题涉及方面分布">
<v-charts
style="height: 310px"
:option="wtlxPieOption"
@ -826,7 +826,7 @@ const fxsjRankOverview = ref({}); // 日常督察总览分县市局
const jsdwRankOverview = ref({}); //
const fxsjChangedRankList = ref([]); //
const jsdwChangedRankList = ref([]); //
const wtlxList = ref([]); //
const wtlxList = ref([]); //
const fxsjYellowBetOverview = ref({
proTotal: 0,
@ -1244,7 +1244,7 @@ const subOneSceneInspRcdxRankAnimation = () => {
subOneRcdcProRankTab.value = (parseInt(subOneRcdcProRankTab.value) % 2 + 1).toString();
};
subOneSceneInspRcdxIntervalId = setInterval(subOneSceneInspRcdxRankAnimation, 3000);
//
//
const subOneSceneProblemTypeRateAnimation = () => {
const temp = subOneSceneProblemTypeRate?.value?.chart;
if (!temp) return;

115
src/views/datav/subonedatav/SubOneVideoInsp.vue

@ -146,54 +146,30 @@
<el-col :span="6">
<datav-card title="实时预警">
<el-scrollbar height="450px">
<div class="message message-error">
<div class="message-title">待处理</div>
<div>
芙蓉-定王台-办案区-问室
湖南省长沙市公安局芙蓉分局定王台派出所
&emsp; 民警单人询的违规问题
</div>
<div class="message-footer flex between">
<span>芙蓉分局定王台派出所</span>
<span>2024-11-18 20:12</span>
</div>
</div>
<div class="message message-info">
<div class="message-title">待处理</div>
<div>
望城-管理中心-办案区-询问室湖南省长沙市望城区公安局法制大队&emsp;
民警单人询的违规问题
</div>
<div class="message-footer flex between">
<span>望城区公安局法制大队</span>
<span>2024-11-18 19:12</span>
</div>
</div>
<div class="message">
<div class="message-title">待处理</div>
<div>
执法办案中心-询问室7湖南省长沙市公安局芙蓉分局蓉园派出所
&emsp;同时讯问多名嫌疑对象
</div>
<div class="message-footer flex between">
<span>芙蓉分局蓉园派出所</span>
<span>2024-11-18 16:12</span>
</div>
</div>
<div class="message">
<div class="message-title">待处理</div>
<div>
开福-直属-执法办案管理-讯询问室湖南省长沙市公安局开福分局法制大队
&emsp;民警单人询的违规问题
<div
class="message message-info pointer"
v-for="item in videoInspections"
:key="item"
:active="item.distributionState === '1'"
@click="handleOpenData"
>
<div class="message-title">
{{
item.distributionState === "1"
? "已处理"
: "待处理"
}}
</div>
<div>{{ item.title }}</div>
<div>{{ item.content }}</div>
<div class="message-footer flex between">
<span>开福分局法制大队</span>
<span>2024-11-18 15:12</span>
<span>{{ item.fsdwGajgmc }}</span>
<span>{{ item.rqsj }}</span>
</div>
</div>
</el-scrollbar>
</datav-card>
<datav-card title="问题类型占比">
<datav-card title="问题涉及方面分布">
<v-charts
style="height: 300px"
:option="ProblemTypeRateChart"
@ -229,6 +205,7 @@ import {
import {
getVideoStatus,
} from "@/api/screen/videoSupervise.ts";
import { listVideoInspection } from "@/api/data/videoInspection";
// region
const route = useRoute();
const currentDepartId = route.query.departId;
@ -469,7 +446,7 @@ const ProblemTypeRateChart = ref({
tooltip: {
trigger: "item",
},
}); //
}); //
// endregion
// region
@ -595,7 +572,7 @@ const subOneVideoTrendAnimation = () => {
});
};
subOneVideoTrendIntervalId = setInterval(subOneVideoTrendAnimation, 2000);
//
//
const subOneVideoProblemTypeRateAnimation = () => {
const temp = subOneVideoProblemTypeRate?.value?.chart;
if (!temp) return;
@ -752,6 +729,25 @@ function handlePlay(item, index) {
activeVideoIndex.value = index;
activeUrl.value = item.videoUrl;
}
const videoInspections = ref([]);
async function getVideoInspection() {
const data = await listVideoInspection({
current: 1,
size: 5,
departId: route.query.departId
});
videoInspections.value = data.records;
}
onMounted(() => {
getVideoInspection();
});
function handleOpenData() {
window.open(router.resolve('/data/VideoInspection').href)
}
</script>
@ -773,37 +769,21 @@ img {
margin-bottom: 10px;
background: linear-gradient(
180deg,
rgba(145, 145, 145, 0) 0%,
rgba(164, 164, 164, 0.26) 98%
rgba(208, 18, 18, 0) 0%,
rgba(255, 0, 0, 0.26) 100%
);
border: 1px solid;
border-image: linear-gradient(
180deg,
rgba(255, 255, 255, 0.28),
rgba(255, 255, 255, 0.26)
rgba(255, 71, 71, 0.59),
rgba(251, 95, 95, 1)
)
1 1;
&.message-error {
background: linear-gradient(
180deg,
rgba(208, 18, 18, 0) 0%,
rgba(255, 0, 0, 0.26) 100%
);
border: 1px solid;
border-image: linear-gradient(
180deg,
rgba(255, 71, 71, 0.59),
rgba(251, 95, 95, 1)
)
1 1;
.message-title {
color: #ff0017;
}
.message-title {
color: #ff0017;
}
&.message-info {
&[active="true"] {
background: linear-gradient(
180deg,
rgba(18, 104, 208, 0) 0%,
@ -826,7 +806,6 @@ img {
font-size: 23px;
font-weight: 700;
margin-bottom: 10px;
color: #597ae9;
}
.message-footer {

278
src/views/mobileSupervise/Inspection.vue

@ -0,0 +1,278 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="督察单位">
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="任务名称">
<el-input
placeholder="请输入任务名称"
v-model="query.nickName"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="督察类型">
<el-select v-model="form.supervisionType" clearable>
<el-option
v-for="item in dict.supervisionType"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex between">
<el-button type="primary" @click="handleShowAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
发布任务</el-button
>
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list">
<el-table-column label="任务名称" prop="taskName" />
<el-table-column
label="督察单位"
prop="supDepartName"
width="120"
/>
<el-table-column
label="参与人员"
prop="testingPerson"
show-overflow-tooltip
/>
<el-table-column
label="任务类型"
prop="supervisionType"
width="100"
align="center"
/>
<el-table-column label="任务内容" prop="taskContent" />
<el-table-column label="督察时间" prop="updateTime" width="280">
<template #default="{ row }">
<span>{{ row.beginTime }}</span>
<span>-</span>
<span>{{ row.endTime }}</span>
</template>
</el-table-column>
<el-table-column label="任务状态">
<template #default="{ row }">
<span v-if="row.taskStatus === 'todo'">执行中</span>
<span v-if="row.taskStatus === 'done'">已完成</span>
</template>
</el-table-column>
<el-table-column label="被督察单位数" prop="" />
<el-table-column label="发现问题数" prop="" />
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button type="primary" link>查看详情</el-button>
<el-button type="primary" link>问题清单</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20, 50]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</div>
<el-dialog
title="发布任务"
v-model="show"
width="1076px"
top="5vh"
style="margin-bottom: 0"
>
<el-scrollbar max-height="66vh">
<el-form
:label-width="150"
ref="formRef"
:model="form"
style="min-height: 66vh"
>
<el-form-item
label="任务名称"
:rules="{
required: true,
message: '请输入任务名称',
trigger: ['blur'],
}"
prop="taskName"
>
<el-input
v-model="form.taskName"
placeholder="请输入任务名称"
/>
</el-form-item>
<el-form-item
label="督察单位"
:rules="{
required: true,
message: '请选择',
}"
prop="supDepartId"
>
<div style="width: 300px">
<depart-tree-select v-model="form.supDepartId" />
</div>
</el-form-item>
<el-form-item
label="督察人员"
:rules="{
required: true,
message: '请选择',
}"
prop="persons"
>
<police-picker v-model="form.persons" />
</el-form-item>
<el-form-item
label="督察类型"
:rules="{
required: true,
message: '请选择',
}"
prop="supervisionType"
>
<el-select
v-model="form.supervisionType"
clearable
style="width: 300px"
>
<el-option
v-for="item in dict.supervisionType"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item
label="督察时间"
prop="times"
:rules="{
required: true,
message: '请选择',
}"
>
<div style="width: 800px">
<el-date-picker
v-model="form.times"
type="datetimerange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</div>
</el-form-item>
<el-form-item
label="任务内容"
prop="times"
:rules="{
required: true,
message: '请选择',
}"
>
<el-input
type="textarea"
v-model="form.taskContent"
:autosize="{ minRows: 6 }"
/>
</el-form-item>
</el-form>
</el-scrollbar>
<footer class="flex end mt-20">
<el-button type="primary" @click="submit" size="large"
>发布</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import {
listInspection,
addInspection,
} from "@/api/mobileSupervision/inspection";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts(["supervisionType"]);
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listInspection(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
getList();
const show = ref(false);
const form = ref({});
const formRef = ref(null);
async function submit() {
await formRef.value.validate();
await addInspection(form.value);
feedback.msgSuccess("发布成功");
show.value = false;
getList();
}
function handleShowAdd() {
show.value = true;
}
</script>
<style lang="scss" scoped>
h5 {
margin-bottom: 10px;
}
.pepole-container > * {
margin-bottom: 8px;
}
</style>

469
src/views/mobileSupervise/TestingAlcohol.vue

@ -0,0 +1,469 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="检测单位">
<depart-tree-select v-model="query.departId" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="任务名称">
<el-input
placeholder="请输入任务名称"
v-model="query.nickName"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex between">
<el-button type="primary" @click="handleShowAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
发布任务</el-button
>
<div>
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list">
<el-table-column label="任务名称" prop="taskName" />
<el-table-column label="检测单位" prop="supDepartName" width="120" />
<el-table-column label="检测人员" prop="persons" show-overflow-tooltip />
<el-table-column label="抽检人数" prop="totalNumber" width="100" align="center" />
<el-table-column
label="检测时间"
prop="updateTime"
width="280"
>
<template #default="{ row }">
<span>{{ row.beginTime }}</span>
<span>-</span>
<span>{{ row.endTime }}</span>
</template>
</el-table-column>
<el-table-column label="未检测人数" prop="notDetectedNumber" width="100" align="center" />
<el-table-column label="未饮酒人数" prop="notDrinkingNumber" width="100" align="center" />
<el-table-column label="饮酒人数" prop="drinkNumber" width="100" align="center" />
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button
type="primary"
link
>任务详情</el-button>
<el-button
type="primary"
link
>检测情况</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20, 50]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</div>
<el-dialog
title="发布任务"
v-model="show"
width="1076px"
top="3vh"
style="margin-bottom: 0"
>
<el-scrollbar max-height="76vh">
<el-form
:label-width="150"
ref="formRef"
:model="form"
style="min-height: 76vh"
>
<el-form-item
label="任务名称"
:rules="{
required: true,
message: '请输入任务名称',
trigger: ['blur'],
}"
prop="taskName"
>
<el-input
v-model="form.taskName"
placeholder="请输入任务名称"
/>
</el-form-item>
<el-form-item
label="检测单位"
:rules="{
required: true,
message: '请选择',
}"
prop="supDepartId"
>
<div style="width: 300px">
<depart-tree-select v-model="form.supDepartId" />
</div>
</el-form-item>
<el-form-item
label="检测人员"
:rules="{
required: true,
message: '请选择',
}"
prop="persons"
>
<police-picker v-model="form.persons" />
</el-form-item>
<el-form-item
label="检测时间"
prop="times"
:rules="{
required: true,
message: '请选择',
}"
>
<div style="width: 800px">
<el-date-picker
v-model="form.times"
type="datetimerange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
/>
</div>
</el-form-item>
<el-form-item
label="检测对象"
prop="dataGenerationMethod"
:rules="{
required: true,
message: '请选择',
}"
>
<el-radio-group v-model="form.dataGenerationMethod">
<el-radio value="Excel导入人员">Excel导入人员</el-radio>
<el-radio value="自定义人员">自定义人员</el-radio>
</el-radio-group>
</el-form-item>
<template v-if="form.dataGenerationMethod === 'Excel导入人员'">
<el-upload
drag
:multiple="false"
:auto-upload="false"
:show-file-list="false"
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
>
<el-icon class="el-icon--upload"
><upload-filled
/></el-icon>
<div class="el-upload__text">
<p>点击或拖拽文件到此区域上传</p>
</div>
</el-upload>
</template>
<template v-if="form.dataGenerationMethod === '自定义人员'">
<h5>筛选条件</h5>
<el-row>
<el-col :span="8">
<el-form-item
label="被抽检次数少于"
prop="filterMinSupNumber"
:rules="{
required: true,
message: '请输入',
}"
>
<el-input-number
controls-position="right"
style="width: 80px"
v-model="form.filterMinSupNumber"
/>
<span class="ml-8"></span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
label="距最后一次检测时间"
prop="filterLastDays"
:rules="{
required: true,
message: '请输入距最后一次检测时间',
}"
>
<el-input-number
controls-position="right"
style="width: 80px"
v-model="form.filterLastDays"
/>
<span class="ml-8"></span>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="有无饮酒历史">
<el-radio-group
v-model="form.filterAlcoholHistory"
>
<el-radio :value="true"></el-radio>
<el-radio :value="false"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item
label="抽检人数"
prop="filterPeopleNumber"
:rules="{
required: true,
message: '请输入抽检人数',
}"
>
<el-input-number
controls-position="right"
style="width: 80px"
v-model="form.filterPeopleNumber"
/>
<span class="ml-8"></span>
</el-form-item>
</el-col>
</el-row>
<div class="flex between v-center">
<h5>被抽检对象</h5>
<el-button
type="primary"
plain
size="small"
@click="form.filterPeopleConditions.push({})"
>
<template #icon>
<icon name="el-icon-Plus" />
</template>
添加部门</el-button
>
</div>
<div>
<div
class="flex between mb-10"
v-for="(item, index) in form.filterPeopleConditions"
:key="index"
>
<div class="flex gap">
<div>
<depart-tree-select
style="width: 280px"
v-model="item.departId"
@change="
() => {
handleGetPersonNumber(item);
}
"
/>
</div>
<el-select
v-model="item.personType"
multiple
clearable
style="width: 280px"
@change="
() => {
handleGetPersonNumber(item);
}
"
>
<el-option
v-for="item in dict.personType"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<el-select
v-model="item.position"
style="width: 180px"
multiple
clearable
@change="
() => {
handleGetPersonNumber(item);
}
"
>
<el-option value="正职">正职</el-option>
<el-option value="副职">副职</el-option>
<el-option value="">无职位</el-option>
</el-select>
<span class="ml-20">
<span
>人数{{
item.polices?.length || 0
}}</span
>
<span></span>
</span>
</div>
<el-button
type="danger"
plain
@click="
form.filterPeopleConditions.splice(index, 1)
"
>删除</el-button
>
</div>
</div>
<div class="flex between v-center">
<h5>被抽检对象名单</h5>
<div>
<el-button
type="primary"
plain
size="small"
@click="handleGenPeople"
v-if="form.peoples.length > 0"
>重新生成抽检对象</el-button
>
</div>
</div>
<div class="text-center" v-if="form.peoples.length === 0">
<el-button type="primary" plain @click="handleGenPeople"
>生成抽检对象</el-button
>
</div>
<div class="flex gap wrap pepole-container">
<el-tag v-for="item in form.peoples" :key="item"
>{{ item.name }}-{{ item.empNo }}</el-tag
>
</div>
</template>
</el-form>
</el-scrollbar>
<footer class="flex end mt-20">
<el-button type="primary" @click="submit" size="large"
>发布</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import { listTestingAlcohol, addTestingAlcohol, getPersonNumber } from "@/api/mobileSupervision/testingAlcohol";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts([, "personType"]);
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listTestingAlcohol(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
getList();
const show = ref(false);
const form = ref({
dataGenerationMethod: "自定义人员",
filterMinSupNumber: 10,
filterLastDays: 60,
filterAlcoholHistory: false,
filterPeopleNumber: 10,
filterPeopleConditions: [],
peoples: [],
});
const formRef = ref(null);
async function submit() {
await formRef.value.validate();
await addTestingAlcohol(form.value);
feedback.msgSuccess('发布成功')
show.value = false;
getList()
}
async function handleGetPersonNumber(item) {
console.log(item);
if (item.departId) {
item.polices = await getPersonNumber(item);
} else {
item.polices = [];
}
}
function handleShowAdd() {
show.value = true;
}
function handleGenPeople() {
const sum = form.value.filterPeopleConditions
.filter((item) => item.polices)
.map((item) => item.polices.length)
.reduce((a, b) => a + b);
const peoples = [];
form.value.filterPeopleConditions
.filter((item) => item.polices)
.forEach((item) => {
const count =
(item.polices.length / sum) * form.value.filterPeopleNumber;
for (let i = 0; i < count; i++) {
addPepole(peoples, item.polices);
}
});
form.value.peoples = peoples;
}
function addPepole(peoples, polices) {
const randomIndex = Math.floor(Math.random() * polices.length);
console.log(randomIndex);
const item = polices[randomIndex];
if (!peoples.includes(item)) {
peoples.push(item);
} else {
addPepole(peoples, polices);
}
}
</script>
<style lang="scss" scoped>
h5 {
margin-bottom: 10px;
}
.pepole-container > * {
margin-bottom: 8px;
}
</style>

2
src/views/sensitivePerception/PoliceNegative.vue

@ -379,7 +379,7 @@
/>
</el-col>
<el-col :span="8">
<h5>问题类型占比</h5>
<h5>问题涉及方面分布</h5>
<v-charts
style="height: 320px"
:option="problemTypePieOptions"

408
src/views/work/BatchDistribute.vue

@ -14,10 +14,23 @@
</el-col>
<el-col :span="6">
<el-form-item label="数据来源">
<el-select v-model="query.source"
clearable>
<el-option label="标准模板" value="标准模板"></el-option>
<el-option label="12337" value="12337"></el-option>
<el-select v-model="query.source" clearable>
<el-option
label="标准模板"
value="标准模板"
></el-option>
<el-option
label="审计监督"
value="审计监督"
></el-option>
<el-option
label="案件核查"
value="案件核查"
></el-option>
<el-option
label="12337"
value="12337"
></el-option>
</el-select>
</el-form-item>
</el-col>
@ -31,12 +44,20 @@
</el-row>
</el-form>
<div class="flex between">
<el-button type="primary" @click="handleShowImport">
<template #icon>
<icon name="el-icon-Top" />
</template>
问题批量下发</el-button
>
<div>
<el-button type="primary" @click="handleShowImport">
<template #icon>
<icon name="el-icon-Top" />
</template>
标准问题批量下发</el-button
>
<el-button type="primary" @click="handleShowAuditImport">
<template #icon>
<icon name="el-icon-Top" />
</template>
审计监督问题批量下发</el-button
>
</div>
<div>
<el-button type="primary" @click="getList">
<template #icon>
@ -84,7 +105,9 @@
</el-table>
</div>
<div class="flex between v-center mt-8">
<div>说明批量下发列表展示问题导入标准模板及其他来源问题导入模板下发的任务情况</div>
<div>
说明批量下发列表展示问题导入标准模板及其他来源问题导入模板下发的任务情况
</div>
<el-pagination
@size-change="getList"
@current-change="getList"
@ -147,7 +170,9 @@
>问题批量导入标准模板.xlsx 下载</a
>
</div>
<div class="mt-10">说明请上传问题批量导入标准模板上传成功后点击下一步进行数据校验</div>
<div class="mt-10">
说明请上传问题批量导入标准模板上传成功后点击下一步进行数据校验
</div>
</template>
<template v-if="activeStep === 1">
<div class="table-container">
@ -314,21 +339,30 @@
</el-form>
</template>
<template v-if="activeStep === 3">
<el-result
icon="success"
title="下发成功"
>
<el-result icon="success" title="下发成功">
<template #sub-title>
<p>
<span>{{ formData.taskName }}</span>
已成功导入系统并完成下发您可通过<span class="link pointer" @click="router.push('/work/BatchDistribute')">批量下发</span> <span class="link pointer" @click="router.push('/query')">综合查询</span>功能进行查看
已成功导入系统并完成下发您可通过<span
class="link pointer"
@click="router.push('/work/BatchDistribute')"
>批量下发</span
>
<span
class="link pointer"
@click="router.push('/query')"
>综合查询</span
>功能进行查看
</p>
</template>
</el-result>
</template>
</div>
<footer class="flex end mt-20 v-center">
<el-button size="large" @click="handlePrev" v-if="activeStep !== 3 && activeStep !== 0"
<el-button
size="large"
@click="handlePrev"
v-if="activeStep !== 3 && activeStep !== 0"
>上一步</el-button
>
<el-button
@ -383,9 +417,265 @@
</div>
</div>
</el-dialog>
<el-dialog v-model="auditImportShow" title="审计监督问题批量下发" width="80vw">
<header class="flex center mb-40">
<el-steps
:space="200"
:active="activeStep"
finish-status="success"
style="width: 800px"
>
<el-step title="数据导入" />
<el-step title="数据校验" />
<el-step title="问题下发" />
<el-step title="完成下发" />
</el-steps>
</header>
<div style="min-height: 50vh">
<template v-if="activeStep === 0">
<el-upload
drag
:multiple="false"
:auto-upload="false"
:show-file-list="false"
v-model:file-list="fileList"
accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
class="mt-20"
>
<template v-if="fileList.length === 0">
<el-icon class="el-icon--upload"
><upload-filled
/></el-icon>
<div class="el-upload__text">
<p>点击选择文件或拖拽文件到此区域上传</p>
</div>
</template>
<template v-else>
<el-icon class="el-icon--upload"><Select /></el-icon>
<div class="el-upload__text">
已选择文件{{ fileList[fileList.length - 1].name }}
</div>
</template>
</el-upload>
<div class="mt-20">
<span>文件模板</span>
<a
class="link"
:href="`${BASE_PATH}/templates/审计监督问题批量导入模板.xlsx`"
target="__blank"
>审计监督问题批量导入模板.xlsx 下载</a
>
</div>
<div class="mt-10">
说明请上传审计监督问题批量导入模板上传成功后点击下一步进行数据校验
</div>
</template>
<template v-if="activeStep === 1">
<div class="table-container">
<el-table :data="importTableData">
<el-table-column
label="问题涉及单位"
prop="discoverTime"
width="180"
>
<template #default="{ row }">
<depart-tree-select
size="small"
v-model="row.involveDepartId"
/>
</template>
</el-table-column>
<el-table-column
label="项目名称"
prop="projectName"
width="110"
/>
<el-table-column
label="问题金额(万元)"
prop="involveMoney"
width="90"
/>
<el-table-column
label="案件名称"
prop="caseName"
width="130"
/>
<el-table-column
label="案件/警情编号"
prop="caseNumber"
width="130"
/>
<el-table-column
label="问题来源"
prop="problemSources"
width="110"
/>
<el-table-column
label="业务类别"
prop="businessTypeName"
width="110"
/>
<el-table-column
label="问题类型"
prop="problemsStr"
width="120"
show-overflow-tooltip
/>
<el-table-column
label="涉及警种"
prop="policeTypeName"
width="90"
/>
<el-table-column
label="问题发现时间"
prop="discoveryTime"
width="160"
/>
<el-table-column
label="具体问题内容"
prop="thingDesc"
show-overflow-tooltip
/>
</el-table>
</div>
</template>
<template v-if="activeStep === 2">
<el-form :model="formData" ref="formRef" style="margin: 0 80px">
<el-form-item
label="任务名称"
prop="taskName"
:rules="{
required: true,
message: '请输入任务名称',
}"
>
<el-input
v-model="formData.taskName"
style="width: 280px"
placeholder="请输入"
/>
</el-form-item>
<el-form-item
label="办理时限"
prop="timeLimit"
:rules="{
required: true,
message: '请选择办理时限',
}"
>
<time-limit-select
v-model="formData.timeLimit"
v-model:maxSignDuration="formData.maxSignDuration"
v-model:maxHandleDuration="
formData.maxHandleDuration
"
v-model:maxExtensionDuration="
formData.maxExtensionDuration
"
/>
</el-form-item>
<el-form-item
label="下发流程"
prop="distributionFlow"
:rules="{
required: true,
message: '请选择下发流程',
}"
>
<el-radio-group v-model="formData.distributionFlow">
<el-radio
v-for="item in dict.distributionFlow"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
</el-form-item>
<el-form-item
label="审核流程"
prop="approvalFlow"
:rules="{
required: true,
message: '请选择审核流程',
}"
>
<div>
<el-radio-group v-model="formData.approvalFlow">
<el-radio
v-for="item in dict.approvalFlow"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
<div class="tips mt-10">
<p>
三级审核 在问题提交办结时需经过所队>二级机构>市局三级审核通过后方可办结
</p>
<p>
二级审核 在问题提交办结时仅需经过所队>二级机构两级审核通过后即可办结
</p>
</div>
</div>
</el-form-item>
<el-form-item label="附件说明" prop="thingFiles">
<file-upload v-model:files="formData.thingFiles" />
</el-form-item>
</el-form>
</template>
<template v-if="activeStep === 3">
<el-result icon="success" title="下发成功">
<template #sub-title>
<p>
<span>{{ formData.taskName }}</span>
已成功导入系统并完成下发您可通过<span
class="link pointer"
@click="router.push('/work/BatchDistribute')"
>批量下发</span
>
<span
class="link pointer"
@click="router.push('/query')"
>综合查询</span
>功能进行查看
</p>
</template>
</el-result>
</template>
</div>
<footer class="flex end mt-20 v-center">
<el-button
size="large"
@click="handlePrev"
v-if="activeStep !== 3 && activeStep !== 0"
>上一步</el-button
>
<el-button
type="primary"
size="large"
@click="handleNext"
v-loading="loading"
>{{ activeStep === 3 ? "确定" : "下一步" }}</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import { listNegativeTask, importNegative, distributeNegative, listGroupByDepart } from "@/api/work/negativeTask";
import {
listNegativeTask,
importNegative,
distributeNegative,
listGroupByDepart,
importAuditNegative,
distributeAuditNegative
} from "@/api/work/negativeTask";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
import { BASE_PATH } from "@/api/request";
@ -394,14 +684,14 @@ const catchStore = useCatchStore();
const dict = catchStore.getDicts([
"approvalFlow",
"distributionFlow",
"businessType"
"businessType",
]);
const router = useRouter()
const router = useRouter();
const query = ref({
size: 10,
current: 1,
category: '0'
category: "0",
});
const list = ref([]);
const total = ref(0);
@ -417,7 +707,7 @@ function reset() {
query.value = {
size: 10,
current: 1,
category: '0'
category: "0",
};
getList();
}
@ -426,20 +716,19 @@ onMounted(() => {
getList();
});
const activeStep = ref(0);
const importShow = ref(false);
const fileList = ref([]);
const loading = ref(false);
const loadingText = ref('')
const loadingText = ref("");
const importTableData = ref([]);
const formData = ref({});
const formRef = ref();
function handleShowImport() {
importShow.value = true
importShow.value = true;
}
function handlePrev() {
@ -453,12 +742,15 @@ async function handleNext() {
const formData = new FormData();
formData.append("file", fileList.value[fileList.value.length - 1].raw);
loading.value = true;
loadingText.value = '数据校验中...'
loadingText.value = "数据校验中...";
try {
importTableData.value = await importNegative(
formData
);
if (importShow.value) {
importTableData.value = await importNegative(formData);
} else {
importTableData.value = await importAuditNegative(formData);
}
} catch (e) {
loading.value = false;
throw e;
@ -482,10 +774,14 @@ async function handleNext() {
if (activeStep.value === 2) {
await formRef.value.validate();
loading.value = true;
loadingText.value = '数据处理中,请稍后...'
loadingText.value = "数据处理中,请稍后...";
formData.value.data = importTableData.value;
try {
await distributeNegative(formData.value);
if (importShow.value) {
await distributeNegative(formData.value);
} else {
await distributeAuditNegative(formData.value);
}
} catch (e) {
loading.value = false;
throw e;
@ -493,39 +789,49 @@ async function handleNext() {
activeStep.value = 3;
loading.value = false;
getList();
return
return;
}
if (activeStep.value === 3) {
importShow.value = false
activeStep.value = 0
formData.value = {}
importTableData.value = []
fileList.value = []
importShow.value = false;
}
}
watch(importShow, (val) => {
if (val) {
activeStep.value = 0
formData.value = {}
importTableData.value = []
fileList.value = []
activeStep.value = 0;
formData.value = {};
importTableData.value = [];
fileList.value = [];
}
})
});
const auditImportShow = ref(false)
watch(auditImportShow, (val) => {
if (val) {
activeStep.value = 0;
formData.value = {};
importTableData.value = [];
fileList.value = [];
}
});
function handleExport12337(id) {
window.open(`${BASE_PATH}/data/petitionComplaint12337/export/result?taksId=${id}`)
window.open(
`${BASE_PATH}/data/petitionComplaint12337/export/result?taksId=${id}`
);
}
const show = ref(false)
const taskDetailList = ref([])
const show = ref(false);
const taskDetailList = ref([]);
async function handleDetailShow(id) {
const data = await listGroupByDepart(id)
const data = await listGroupByDepart(id);
taskDetailList.value = data;
show.value = true;
}
</script>
<style lang="scss" scoped>
</style>
function handleShowAuditImport() {
auditImportShow.value = true;
}
</script>
Loading…
Cancel
Save