Browse Source

20250328

main
wxc 10 months ago
parent
commit
deafd43ec8
  1. 3
      index.html
  2. 3
      package.json
  3. 1
      public/decoder.js
  4. BIN
      public/decoder.wasm
  5. 1
      public/jessibuca.js
  6. 1
      public/js/liveplayer-lib.min.js
  7. 8
      src/App.vue
  8. 7
      src/api/books.ts
  9. 6
      src/api/data/caseVerif.ts
  10. 8
      src/api/data/mailbox.ts
  11. 7
      src/api/data/petition12337.ts
  12. 37
      src/api/data/supervisionNotify.ts
  13. 6
      src/api/data/videoInspection.ts
  14. 9
      src/api/rightsComfort/comfort.ts
  15. 23
      src/api/rightsComfort/comfortPacks.ts
  16. 2
      src/api/screen/jwpy.ts
  17. 8
      src/api/system/depart.ts
  18. 30
      src/api/system/handleResultMaping.ts
  19. 48
      src/api/system/videoConfig.ts
  20. 15
      src/api/work/myCountersign.ts
  21. 7
      src/api/work/negativeTask.ts
  22. 151
      src/components/comfort/dialog.vue
  23. 10
      src/components/data/gj-import.vue
  24. 2
      src/components/datav/date-picker.vue
  25. 10
      src/components/datav/message.vue
  26. 3
      src/components/datav/statistic.vue
  27. 10
      src/components/datav/tab-item.vue
  28. 99
      src/components/datav/tabs.vue
  29. 2
      src/components/file/list.vue
  30. 421
      src/components/file/preview.vue
  31. 5
      src/components/file/upload.vue
  32. 34
      src/components/home/work/index.vue
  33. 105
      src/components/home/work/my-comfort.vue
  34. 8
      src/components/negative/action-history.vue
  35. 161
      src/components/negative/add.vue
  36. 2
      src/components/negative/apply-completion.vue
  37. 2
      src/components/negative/apply-countersign.vue
  38. 5
      src/components/negative/apply-extension.vue
  39. 26
      src/components/negative/description.vue
  40. 96
      src/components/negative/dialog.vue
  41. 27
      src/components/negative/verify-description.vue
  42. 74
      src/components/negative/verify.vue
  43. 1
      src/components/negativeInfo/depart-dialog.vue
  44. 7
      src/components/query-select.vue
  45. 60
      src/components/video-play.vue
  46. 20
      src/layout/components/Aside.vue
  47. 4
      src/router/routes.ts
  48. 83
      src/style/public.scss
  49. 4
      src/utils/feedback.ts
  50. 347
      src/views/books/Audit.vue
  51. 3
      src/views/books/Gabxf.vue
  52. 185
      src/views/books/Mail12337.vue
  53. 769
      src/views/data/Ajhc.vue
  54. 49
      src/views/data/Gabxf.vue
  55. 46
      src/views/data/Gjxf.vue
  56. 129
      src/views/data/ImportRecords.vue
  57. 6
      src/views/data/Mail12337.vue
  58. 196
      src/views/data/Mailbox.vue
  59. 628
      src/views/data/VideoInspection.vue
  60. 1262
      src/views/datav/AuditSuper.vue
  61. 48
      src/views/datav/CaseVerif.vue
  62. 4
      src/views/datav/Jwpy.vue
  63. 2398
      src/views/datav/SceneInsp.vue
  64. 73
      src/views/datav/VideoInsp.vue
  65. 2
      src/views/datav/subonedatav/SubOneAuditSuper.vue
  66. 2
      src/views/datav/subonedatav/SubOneCaseVerif.vue
  67. 3
      src/views/datav/subonedatav/SubOneMailVisits.vue
  68. 10
      src/views/datav/subonedatav/SubOneSceneInsp.vue
  69. 1418
      src/views/datav/subonedatav/SubOneVideoInsp.vue
  70. 13
      src/views/rightsComfort/Comfort.vue
  71. 445
      src/views/rightsComfort/ComfortPacks.vue
  72. 514
      src/views/rightsComfort/MyComfort.vue
  73. 82
      src/views/rightsComfort/Rights.vue
  74. 4
      src/views/sensitivePerception/Model.vue
  75. 28
      src/views/sensitivePerception/ModelClue.vue
  76. 29
      src/views/sensitivePerception/ModelClueManual.vue
  77. 2
      src/views/sensitivePerception/ModelClueTask.vue
  78. 251
      src/views/system/HandleResultMaping.vue
  79. 56
      src/views/system/Menu.vue
  80. 147
      src/views/system/Police.vue
  81. 295
      src/views/system/VideoConfig.vue
  82. 1
      src/views/system/Wqzg.vue
  83. 29
      src/views/work/Alarm.vue
  84. 26
      src/views/work/BatchDistribute.vue
  85. 3
      src/views/work/Done.vue
  86. 528
      src/views/work/MyCountersign.vue
  87. 14
      src/views/work/NegativeImport.vue
  88. 6
      src/views/work/NegativeTask.vue
  89. 185
      src/views/work/News.vue
  90. 154
      src/views/work/Query.vue
  91. 72
      src/views/work/Todo.vue
  92. 1813
      src/views/work/VerifySubmit.vue

3
index.html

@ -15,5 +15,8 @@
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
<script src="/js/authen.js"></script> <script src="/js/authen.js"></script>
<script src="/js/pnxclient.js"></script> <script src="/js/pnxclient.js"></script>
<!-- 视频 -->
<script src="/js/liveplayer-lib.min.js"></script>
<script src="/jessibuca.js"></script>
</body> </body>
</html> </html>

3
package.json

@ -15,6 +15,7 @@
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^2.3.1", "@element-plus/icons-vue": "^2.3.1",
"@liveqing/liveplayer-v3": "^3.7.35",
"@univerjs/core": "^0.2.5", "@univerjs/core": "^0.2.5",
"@univerjs/data-validation": "^0.2.5", "@univerjs/data-validation": "^0.2.5",
"@univerjs/design": "^0.2.5", "@univerjs/design": "^0.2.5",
@ -37,7 +38,7 @@
"echarts": "^5.4.3", "echarts": "^5.4.3",
"element-plus": "^2.8.8", "element-plus": "^2.8.8",
"flv.js": "^1.6.2", "flv.js": "^1.6.2",
"hls.js": "^1.5.18", "hls.js": "^1.5.20",
"install": "^0.13.0", "install": "^0.13.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"moment": "^2.30.1", "moment": "^2.30.1",

1
public/decoder.js

File diff suppressed because one or more lines are too long

BIN
public/decoder.wasm

Binary file not shown.

1
public/jessibuca.js

File diff suppressed because one or more lines are too long

1
public/js/liveplayer-lib.min.js vendored

File diff suppressed because one or more lines are too long

8
src/App.vue

@ -1,14 +1,14 @@
<template> <template>
<el-config-provider :locale="elConfig.locale" :z-index="elConfig.zIndex" > <el-config-provider :locale="elConfig.locale" :z-index="elConfig.zIndex">
<router-view /> <router-view />
</el-config-provider> </el-config-provider>
</template> </template>
<script setup> <script setup>
import zhCn from 'element-plus/es/locale/lang/zh-cn' import zhCn from "element-plus/es/locale/lang/zh-cn";
const elConfig = { const elConfig = {
zIndex: 3000, zIndex: 3000,
locale: zhCn locale: zhCn,
} };
</script> </script>

7
src/api/books.ts

@ -29,3 +29,10 @@ export function listNegativeAjhc(query) {
query query
}); });
} }
export function listNegativeAudit(query) {
return request.get({
url: `/negative/books/audit`,
query
});
}

6
src/api/data/caseVerif.ts

@ -33,3 +33,9 @@ export function distributeCaseVerif(body) {
body body
}); });
} }
export function getNegativeId(originId) {
return request.get({
url: '/data/caseVerif/getNegativeId?originId=' + originId
});
}

8
src/api/data/mailbox.ts

@ -0,0 +1,8 @@
import request from "@/api/request";
export function listMailbox(query) {
return request.get({
url: '/data/mailbox',
query
});
}

7
src/api/data/petition12337.ts

@ -26,3 +26,10 @@ export function distributePetitionComplaint12337(body) {
body body
}); });
} }
export function listPetitionComplaint12337Books(query) {
return request.get({
url: '/negative/books/mail12337',
query
});
}

37
src/api/data/supervisionNotify.ts

@ -50,45 +50,12 @@ export function getSupervisionNotifyMap(times) {
/** /**
* *
*/ */
export function getYellowBetDrug(times) { export function getYellowBetDrug(times, dictValue) {
return request.get({ return request.get({
url: `/datav/supervisonNotify/getYellowBetDrug?beginTime=${times[0]}&endTime=${times[1]}` url: `/datav/supervisonNotify/getYellowBetDrug?beginTime=${times[0]}&endTime=${times[1]}&dictValue=${dictValue}`
}); });
} }
// 枪支管理数据
export function getGunController(times) {
return request.get({
url: `/datav/supervisonNotify/getGunController?beginTime=${times[0]}&endTime=${times[1]}`
});
}
// 枪支管理数据
export function getCompanyProblem(times) {
return request.get({
url: `/datav/supervisonNotify/getCompanyProblem?beginTime=${times[0]}&endTime=${times[1]}`
});
}
// 执法办案数据
export function getHandleCase(times) {
return request.get({
url: `/datav/supervisonNotify/getHandleCase?beginTime=${times[0]}&endTime=${times[1]}`
});
}
// 枪支管理数据
export function getCheckBeer(times) {
return request.get({
url: `/datav/supervisonNotify/getCheckBeer?beginTime=${times[0]}&endTime=${times[1]}`
});
}
export function getWorkDynamics(times) { export function getWorkDynamics(times) {
return request.get({ return request.get({
url: `/datav/supervisonNotify/getWorkDynamics?beginTime=${times[0]}&endTime=${times[1]}` url: `/datav/supervisonNotify/getWorkDynamics?beginTime=${times[0]}&endTime=${times[1]}`

6
src/api/data/videoInspection.ts

@ -19,3 +19,9 @@ export function distributeData(body) {
body body
}); });
} }
export function updateState(id, state) {
return request.put({
url: `/videoInspection/state/${id}?state=${state}`
});
}

9
src/api/rightsComfort/comfort.ts

@ -8,7 +8,7 @@ export function listComfort(query) {
}); });
} }
export function listTodos(query) { export function listComfortTodos(query) {
return request.get({ return request.get({
url: `/comfort/todo`, url: `/comfort/todo`,
query: query query: query
@ -35,6 +35,13 @@ export function applyComfort(body) {
}); });
} }
export function updateComfort(body) {
return request.put({
url: `/comfort`,
body
});
}
export function delComfort(id) { export function delComfort(id) {
return request.del({ return request.del({
url: `/comfort/` + id url: `/comfort/` + id

23
src/api/rightsComfort/comfortPacks.ts

@ -0,0 +1,23 @@
import request from "@/api/request";
export function listComfortPacks(query) {
return request.get({
url: `/comfort/packs`,
query
});
}
export function getComfortPacks(id) {
return request.get({
url: `/comfort/packs/${id}`
});
}
export function addComfortPacks(body) {
return request.post({
url: `/comfort/packs`,
body
});
}

2
src/api/screen/jwpy.ts

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

8
src/api/system/depart.ts

@ -58,9 +58,15 @@ export function updateDepart(body) {
}); });
} }
export function delDepart(id) { export function delDepart(id) {
return request.del({ return request.del({
url: `/depart/${id}` url: `/depart/${id}`
}); });
} }
// 获取分县市局树结构
export function getCountyAndCityBureausTree() {
return request.get({
url: `/depart/tree/countyAndCityBureaus`
});
}

30
src/api/system/handleResultMaping.ts

@ -0,0 +1,30 @@
import request from "@/api/request";
export function listHandleResultMaping(query) {
return request.get({
url: '/handleResultMaping',
query
});
}
export function addHandleResultMaping(body) {
return request.post({
url: '/handleResultMaping',
body
});
}
export function updateHandleResultMaping(body) {
return request.put({
url: '/handleResultMaping',
body
});
}
export function delHandleResultMaping(id) {
return request.del({
url: '/handleResultMaping/' + id
});
}

48
src/api/system/videoConfig.ts

@ -0,0 +1,48 @@
import request from "@/api/request";
export function listVideoConfig(query) {
return request.get({
url: '/videoConfig',
query
});
}
export function getVideoWsUrl() {
return request.get({
url: '/videoConfig/getVideoWsUrl'
});
}
export function addVideoConfig(body) {
return request.post({
url: '/videoConfig',
body
});
}
export function updateVideoConfig(body) {
return request.put({
url: '/videoConfig',
body
});
}
export function delVideoConfig(id) {
return request.del({
url: '/videoConfig/' + id
});
}
export function listDevice(query) {
return request.get({
url: '/videoConfig/device',
query
});
}
export function listVideoConfigByDepartId(departId) {
return request.get({
url: '/videoConfig/depart/' + departId
});
}

15
src/api/work/myCountersign.ts

@ -0,0 +1,15 @@
import request from "@/api/request";
export function listMyCountersign(query) {
return request.get({
url: `/work/countersign`,
query
});
}
export function negativeExport(query) {
return request.post({
url: `/work/countersign/export/excel`,
query
});
}

7
src/api/work/negativeTask.ts

@ -7,13 +7,6 @@ export function listNegativeTask(query) {
}); });
} }
export function listNegativeTaskImport(query) {
return request.get({
url: `/negativeTask/importList`,
query
});
}
export function importNegative(body) { export function importNegative(body) {
return request.post({ return request.post({
url: `/negativeTask/import`, url: `/negativeTask/import`,

151
src/components/comfort/dialog.vue

@ -16,60 +16,76 @@
<div class="col col-6"> <div class="col col-6">
<label>性别</label> <label>性别</label>
<span> <span>
<span v-if="comfort.person.sex === 0"></span> <span v-if="comfort.person?.sex === 0"></span>
<span v-if="comfort.person.sex === 1"></span> <span v-if="comfort.person?.sex === 1"></span>
</span> </span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>出生年月</label> <label>出生年月</label>
<span>{{ comfort.person.birthday }}</span> <span>{{ comfort.person?.birthday }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>文化程度</label> <label>文化程度</label>
<span>{{ comfort.person.levelEducation }}</span> <span>{{ comfort.person?.levelEducation }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>政治面貌</label> <label>政治面貌</label>
<span>{{ comfort.person.politicCountenance }}</span> <span>{{ comfort.person?.politicCountenance }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>身份证号码</label> <label>身份证号码</label>
<span>{{ comfort.person.idCode }}</span> <span>{{ comfort.person?.idCode }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>联系电话</label> <label>联系电话</label>
<span>{{ comfort.person.mobile }}</span> <span>{{ comfort.person?.mobile }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>单位</label> <label>单位</label>
<span>{{ comfort.person.departName }}</span> <span>{{ comfort.person?.departName }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>职务</label> <label>职务</label>
<span>{{ comfort.person.job }}</span> <span>{{ comfort.person?.job }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>警号</label> <label>警号</label>
<span>{{ comfort.person.empNo }}</span> <span>{{ comfort.person?.empNo }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>警衔</label> <label>警衔</label>
<span>{{ comfort.person.policeRank }}</span> <span>{{ comfort.person?.policeRank }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>开户行</label> <label>开户行</label>
<span>{{ comfort.person.bankCard }}</span> <span>{{ comfort.person?.bankCard }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>所属支行</label> <label>所属支行</label>
<span>{{ comfort.person.bankBranch }}</span> <span>{{ comfort.person?.bankBranch }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>银行账号</label> <label>银行账号</label>
<span>{{ comfort.person.bankCardAccount }}</span> <span>{{ comfort.person?.bankCardAccount }}</span>
</div> </div>
</div> </div>
<el-divider /> <el-divider />
<template v-if="comfort.apply.isSelf === '0'">
<div class="row">
<div class="col col-6">
<label>代理人关系</label>
<span>{{
comfort.apply.relation === "1" ? "同事" : "亲属"
}}</span>
</div>
<div class="col col-6">
<label>代理人姓名</label>
<span>{{ comfort.apply.agentName }}</span>
</div>
</div>
<el-divider />
</template>
<h3>案发情况</h3> <h3>案发情况</h3>
<div class="row"> <div class="row">
<div class="col col-6"> <div class="col col-6">
@ -82,7 +98,7 @@
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>受伤程度</label> <label>受伤程度</label>
<span>{{ comfort.applyPerson.injurySeverity }}</span> <span>{{ comfort.applyPerson.injurySeverityName }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>办案单位</label> <label>办案单位</label>
@ -109,7 +125,7 @@
<h3>佐证材料</h3> <h3>佐证材料</h3>
<div> <div>
<template v-if="comfort.apply.documentFile"> <template v-if="comfort.apply.documentFile">
<file-todos <file-list
:files="JSON.parse(comfort.apply.documentFile)" :files="JSON.parse(comfort.apply.documentFile)"
/> />
</template> </template>
@ -123,42 +139,14 @@
<el-divider /> <el-divider />
<h3>审批流程</h3> <h3>审批流程</h3>
<div class="comments-container flex gap-20"> <div class="comments-container flex gap-20">
<div class="item"> <div class="item" v-for="item in comfort.approves" :key="item">
<div class="flex center mb-20 relative comments-header"> <div class="flex center mb-20 relative comments-header">
<icon <template v-if="item.returnFlag !== null">
name="el-icon-CircleCheck"
:size="41"
color="var(--primary-color)"
/>
</div>
<h1 class="text-center mb-16">
<span class="text-primary">申请抚慰</span>
</h1>
<h2 class="text-center mb-20">
{{ comfort.apply.applicantEmpName }}
</h2>
<div style="padding: 8px">
<h4 class="text-right">
{{ comfort.apply.applyDate }}
</h4>
</div>
</div>
<div class="item">
<div class="flex center mb-20 relative comments-header">
<template
v-if="
comfort.approves.find((item) => item.step === 2)
"
>
<icon <icon
name="local-icon-return" name="local-icon-return"
:size="41" :size="41"
color="#FF0606" color="#FF0606"
v-if=" v-if="item.returnFlag"
comfort.approves.find(
(item) => item.step === 2
).returnFlag
"
/> />
<icon <icon
name="el-icon-CircleCheck" name="el-icon-CircleCheck"
@ -170,51 +158,29 @@
<div class="icon" v-else></div> <div class="icon" v-else></div>
</div> </div>
<h1 class="text-center mb-16"> <h1 class="text-center mb-16">
<span>待审批</span> <span
</h1> :class="
<h2 class="text-center mb-20"> item.returnFlag === null
维权专干 {{ comfort.apply.approver }} ? ''
</h2> : item.returnFlag
<div style="padding: 8px"> ? 'text-danger'
<h3>{{}}</h3> : 'text-primary'
<p style="font-weight: 700">{{}}</p>
<h4 class="text-right">{{}}</h4>
</div>
</div>
<div class="item">
<div class="flex center mb-20 relative comments-header">
<template
v-if="
comfort.approves.find((item) => item.step === 2)
" "
>{{ item.actionName }}</span
> >
<icon
name="local-icon-return"
:size="41"
color="#FF0606"
v-if="
comfort.approves.find(
(item) => item.step === 2
).returnFlag
"
/>
<icon
name="el-icon-CircleCheck"
:size="41"
color="var(--primary-color)"
v-else
/>
</template>
<div class="icon" v-else></div>
</div>
<h1 class="text-center mb-16">
<span>待审批</span>
</h1> </h1>
<h2 class="text-center mb-20">市局 维权专干</h2> <h2 class="text-center mb-20">{{ item.handleName }}</h2>
<div style="padding: 8px"> <div style="padding: 8px">
<h3>{{}}</h3> <h4>
<p style="font-weight: 700">{{}}</p> {{ item.createTime }}
<h4 class="text-right">{{}}</h4> </h4>
<h3>
<span>{{ item.commentLabel }}</span>
</h3>
<p style="font-weight: 700">
{{ item.comments }}
</p>
</div> </div>
</div> </div>
</div> </div>
@ -238,7 +204,7 @@
<el-form <el-form
label-position="top" label-position="top"
ref="formRef" ref="formRef"
:model="form" :model="formData"
style="height: 400px" style="height: 400px"
> >
<el-form-item <el-form-item
@ -337,10 +303,10 @@ async function submit() {
returnFlag: formData.value.returnFlag, returnFlag: formData.value.returnFlag,
comments: formData.value.comments, comments: formData.value.comments,
}); });
approveShow.value = false approveShow.value = false;
formData.value = {}; formData.value = {};
feedback.msgSuccess("操作成功"); feedback.msgSuccess("操作成功");
dialogShow.value = false dialogShow.value = false;
emit("update"); emit("update");
} }
</script> </script>
@ -356,7 +322,7 @@ async function submit() {
content: ""; content: "";
position: absolute; position: absolute;
top: 50%; top: 50%;
right: calc(50% + 30px); right: calc(50% + 25px);
width: calc(100% - 30px); width: calc(100% - 30px);
border-top: 2px solid var(--second-color); border-top: 2px solid var(--second-color);
} }
@ -388,6 +354,7 @@ async function submit() {
font-size: 12px; font-size: 12px;
color: #666; color: #666;
font-weight: 500; font-weight: 500;
margin-top: 0;
} }
p { p {
color: #333; color: #333;

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

@ -152,6 +152,14 @@
title="导入成功" title="导入成功"
:sub-title="` 已成功导入${importTableData.length}条数据。`" :sub-title="` 已成功导入${importTableData.length}条数据。`"
> >
<template #sub-title>
<p>已成功导入{{ importTableData.length }}条数据您可通过<span
class="link pointer"
@click="router.push('/data/ImportRecords')"
>导入记录</span
>功能查看导入记录
</p>
</template>
</el-result> </el-result>
</template> </template>
</div> </div>
@ -243,6 +251,8 @@ watch(
} }
} }
); );
const router = useRouter();
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
</style> </style>

2
src/components/datav/date-picker.vue

@ -17,7 +17,7 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import moment from 'moment'
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {

10
src/components/datav/message.vue

@ -3,7 +3,10 @@
<div class="message" :type="type"> <div class="message" :type="type">
<div class="message-title">{{ title }}</div> <div class="message-title">{{ title }}</div>
<div class="message-content">{{ content }}</div> <div class="message-content">{{ content }}</div>
<div class="message-footer flex end"> <div class="message-footer flex between v-center">
<div>
<slot name="link"></slot>
</div>
<span>{{ date }}</span> <span>{{ date }}</span>
</div> </div>
</div> </div>
@ -26,6 +29,10 @@ const props = defineProps( {
date: { date: {
type: String, type: String,
required: true required: true
},
files: {
type: Array,
default: []
} }
}) })
@ -57,4 +64,5 @@ const messageClass = computed(() => `message ${props.type}`);
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
</style> </style>

3
src/components/datav/statistic.vue

@ -22,10 +22,11 @@ const props = defineProps({
}, },
// //
isDecimal: { isDecimal: {
type: String, type: Boolean,
default: false default: false
} }
}); });
const value = ref(props.value); const value = ref(props.value);
watch(() => props.value, (val) => { watch(() => props.value, (val) => {
value.value = val; value.value = val;

10
src/components/datav/tab-item.vue

@ -4,7 +4,9 @@
</div> </div>
</template> </template>
<script setup> <script setup>
defineProps({ import { onMounted } from "vue";
const props = defineProps({
label: { label: {
type: String, type: String,
}, },
@ -13,6 +15,12 @@ defineProps({
}, },
}); });
const activeTab = inject("activeTab"); const activeTab = inject("activeTab");
const registerTab = inject('registerTab');
onMounted(() => {
registerTab({ name: props.name, label: props.label });
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

99
src/components/datav/tabs.vue

@ -2,17 +2,16 @@
<div class="tabs"> <div class="tabs">
<el-scrollbar> <el-scrollbar>
<div class="tab-header flex mb-20" v-if="type === ''" :size="size"> <div class="tab-header flex mb-20" v-if="type === ''" :size="size">
<div <div
class="tab-title-item" class="tab-title-item"
v-for="item in slots" v-for="item in tabs"
:key="item.props.name" :key="item.name"
:active="item.props.name === activeTab" :active="item.name === activeTab"
@click="handleChangeActiveTab(item.props.name)" @click="handleChangeActiveTab(item)"
>
> {{ item.label }}
{{ item.props.label }} </div>
</div> </div>
</div>
</el-scrollbar> </el-scrollbar>
<div class="tabs-content"> <div class="tabs-content">
<slot></slot> <slot></slot>
@ -23,17 +22,19 @@
> >
<div <div
class="tab-title-item" class="tab-title-item"
v-for="item in slots" v-for="item in tabs"
:key="item.props.name" :key="item.name"
:active="item.props.name === activeTab" :active="item.name === activeTab"
@click="handleChangeActiveTab(item.props.name)" @click="handleChangeActiveTab(item)"
> >
{{ item.props.label }} {{ item.label }}
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { computed } from "vue";
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: String, type: String,
@ -45,33 +46,51 @@ const props = defineProps({
}, },
size: { size: {
type: String, type: String,
default: "" default: "",
} },
}); });
const slots = useSlots().default();
const emit = defineEmits(["update:modelValue"]); const emit = defineEmits(["update:modelValue"]);
const activeTab = ref(props.modelValue || slots[0].props.name);
watch(() => props.modelValue, () => {
activeTab.value = props.modelValue
})
watch(activeTab, (val) => {
emit("update:modelValue", val);
})
const tabs = ref([]);
const activeTab = ref(props.modelValue);
const registerTab = (tab) => {
if (!tabs.value.some((t) => t.name === tab.name)) {
tabs.value.push(tab);
if (!activeTab.value) {
activeTab.value = tab.name
}
}
};
provide("registerTab", registerTab);
provide("activeTab", activeTab); provide("activeTab", activeTab);
watch(
() => props.modelValue,
() => {
activeTab.value = props.modelValue;
}
);
watch(activeTab, (val) => {
emit("update:modelValue", val);
});
function handleChangeActiveTab(name) { function handleChangeActiveTab(item) {
activeTab.value = name; activeTab.value = item.name;
emit("update:modelValue", name); emit("update:modelValue", item.name);
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.tab-header { .tab-header {
width: max-content; width: max-content;
gap: 20px; > * {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
.tab-title-item { .tab-title-item {
font-size: 22px; font-size: 22px;
line-height: 34px; line-height: 34px;
@ -80,16 +99,19 @@ function handleChangeActiveTab(name) {
cursor: pointer; cursor: pointer;
&[active="true"] { &[active="true"] {
color: #fff; color: #fff;
border-color: #28E6FF; border-color: #28e6ff;
} }
} }
&[size=small] { &[size="small"] {
gap: 12px; > * {
margin-right: 12px;
&:last-child {
margin-right: 0;
}
}
.tab-title-item { .tab-title-item {
font-size: 19px; font-size: 19px;
} }
} }
} }
.tab-title { .tab-title {
@ -112,10 +134,9 @@ function handleChangeActiveTab(name) {
&:last-child { &:last-child {
border-radius: 0 103px 103px 0; border-radius: 0 103px 103px 0;
} }
&:only-child { &:only-child {
border-radius: 103px; /* 当只有唯一一个元素时,设置所有四个角的圆角 */ border-radius: 103px; /* 当只有唯一一个元素时,设置所有四个角的圆角 */
} }
} }
} }
</style> </style>

2
src/components/file/list.vue

@ -429,7 +429,7 @@ function rotateRight() {
.img-container { .img-container {
img { img {
max-height: 100%; max-height: 100vh;
&:hover { &:hover {
cursor: pointer; cursor: pointer;
} }

421
src/components/file/preview.vue

@ -0,0 +1,421 @@
<template>
<div class="file-preview-wrapper flex overlay" v-if="preview">
<el-scrollbar height="100vh">
<div class="file-list">
<section
v-for="(item, index) in files"
:key="index"
class="flex gap v-center pointer"
:active="files.indexOf(activeFile) === index"
@click="filePreview(item)"
>
<icon :name="getIconName(item.fileName)" :size="24" />
<span>{{ item.fileName }}</span>
</section>
</div>
</el-scrollbar>
<div class="file-content flex center v-center" @click="preview = false">
<div
class="img-container flex center"
v-if="getFileType(activeFile.fileName) === FileType.IMG"
@wheel="wheel"
>
<img
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
ref="imgRef"
@click.stop
:style="{
transform: `rotate(${rotate}deg) scale(${scale}) translate(${translateX}px, ${translateY}px)`,
}"
@mousedown="mousedown"
@mousemove="mousemove"
@mouseup="mouseup"
draggable="false"
/>
<button
class="rotate-left-btn pointer"
@click.stop.prevent="rotateLeft"
size="small"
title="左旋转"
>
<icon name="local-icon-rotate-left" :size="28" />
</button>
<button
class="rotate-right-btn pointer"
@click.stop.prevent="rotateRight"
size="small"
title="右旋转"
>
<icon name="local-icon-rotate-right" :size="28" />
</button>
</div>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.PDF"
>
<iframe
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
style="height: 100vh; width: 900px"
></iframe>
</template>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.MP3"
>
<audio controls style="width: 50vw">
<source
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
type="audio/mp3"
/>
</audio>
</template>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.MP4"
>
<video controls @click.stop style="max-height: 100vh">
<source
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
type="video/mp4"
/>
</video>
</template>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.WORD"
>
<vue-office-docx
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
style="height: 100vh; width: 900px"
@error="fileRrror = true"
v-if="!fileRrror"
@click.stop
/>
<div v-else class="error flex column text-center">
<span style="padding: 20px"
>文件预览解析错误如有需要请下载到本地预览</span
>
</div>
</template>
<template
v-else-if="
getFileType(activeFile.fileName) === FileType.EXCEL &&
activeFile.fileName.toLocaleLowerCase().endsWith('.xlsx')
"
>
<vue-office-excel
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
style="height: 100vh; width: 60vw"
@error="fileRrror = true"
v-if="!fileRrror"
@click.stop
/>
<div v-else class="error flex column text-center">
<span style="padding: 20px"
>文件预览解析错误如有需要请下载到本地预览</span
>
</div>
</template>
<template v-else>
<div style="background: #fff">
<el-result
icon="error"
title="不支持预览"
sub-title="该文件格式暂不支持预览,请下载预览"
style="background: #fff; width: 600px; height: 400px"
@click.stop
>
<template #extra>
<el-button
type="primary"
text
size="large"
@click="download"
>下载文件</el-button
>
</template>
</el-result>
</div>
</template>
<div class="file-number" @click.stop>
<span
>{{ files.indexOf(activeFile) + 1 }} /
{{ files.length }}</span
>
</div>
<button
class="left-btn pointer"
@click.stop.prevent="prev"
v-if="files.length > 1"
>
<icon name="el-icon-ArrowLeftBold" :size="28" />
</button>
<button
class="right-btn pointer"
@click.stop.prevent="next"
v-if="files.length > 1"
>
<icon name="el-icon-ArrowRightBold" :size="28" />
</button>
</div>
<div class="close-btn"></div>
<button class="close-btn pointer" @click="preview = false">
<icon name="el-icon-Close" :size="28" />
</button>
<el-button class="download-btn" @click="download" type="primary" plain>
<template #icon>
<icon name="el-icon-Download" :size="20" />
</template>
下载文件
</el-button>
</div>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
import { FileType } from "@/enums/fileEnums";
import { getFileType, getIconName } from "@/utils/util";
import "@vue-office/docx/lib/index.css";
import "@vue-office/excel/lib/index.css";
import VueOfficeDocx from "@vue-office/docx";
import VueOfficeExcel from "@vue-office/excel";
const props = defineProps({
files: {
type: Array,
default: () => [],
},
show: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:show"]);
const preview = ref(false);
const activeFile = ref({});
watch(
() => props.show,
(val) => {
preview.value = val;
nextTick(() => {
if (
val &&
Object.keys(activeFile.value).length === 0 &&
props.files.length > 0
) {
activeFile.value = props.files[0];
rotate.value = 0;
scale.value = 1;
translateX.value = 0;
translateY.value = 0;
moveFlag = false;
}
});
}
);
watch(preview, (val) => {
emit("update:show", val);
});
const rotate = ref(0);
const scale = ref(0);
const translateX = ref(0);
const translateY = ref(0);
let moveFlag = false;
let initialX = 0;
let initialY = 0;
const fileRrror = ref(false);
function filePreview(file) {
preview.value = true;
activeFile.value = file;
rotate.value = 0;
scale.value = 1;
translateX.value = 0;
translateY.value = 0;
moveFlag = false;
}
function download() {
window.open(`${BASE_PATH}/file/stream/${activeFile.value.filePath}`);
}
function prev() {
const index = props.files.indexOf(activeFile.value);
if (index === 0) {
filePreview(props.files[props.files.length - 1]);
} else {
filePreview(props.files[index - 1]);
}
}
function next() {
const index = props.files.indexOf(activeFile.value);
if (index === props.files.length - 1) {
filePreview(props.files[0]);
} else {
filePreview(props.files[index + 1]);
}
}
function wheel(event) {
if (event.deltaY > 0 && scale.value > 0.5) {
scale.value -= 0.1;
}
if (event.deltaY < 0) {
scale.value += 0.1;
}
}
function mousedown() {
moveFlag = true;
initialX = event.clientX;
initialY = event.clientY;
}
function mousemove(event) {
if (!moveFlag) {
return;
}
if (rotate.value % 360 === 0) {
translateX.value += event.clientX - initialX;
translateY.value += event.clientY - initialY;
}
if (rotate.value === 90) {
translateY.value -= event.clientX - initialX;
translateX.value += event.clientY - initialY;
}
if (rotate.value === 180) {
translateX.value -= event.clientX - initialX;
translateY.value -= event.clientY - initialY;
}
if (rotate.value === 270) {
translateY.value += event.clientX - initialX;
translateX.value -= event.clientY - initialY;
}
initialX = event.clientX;
initialY = event.clientY;
}
function mouseup(event) {
moveFlag = false;
}
function rotateLeft() {
if (rotate.value === 360) {
rotate.value = 0;
} else {
rotate.value += 90;
}
}
function rotateRight() {
if (rotate.value === 0) {
rotate.value = 270;
} else {
rotate.value -= 90;
}
}
</script>
<style lang="scss" scoped>
.file-preview-wrapper {
.file-list {
width: 15vw;
height: 100vh;
padding: 16px 8px;
background-color: #fff;
box-sizing: border-box;
section {
padding: 8px 16px;
border: 2px solid transparent;
background-color: #fff;
&:hover {
color: var(--primary-color);
font-weight: 700;
}
&[active="true"] {
border-color: var(--primary-color);
}
span {
width: calc(100% - 32px);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
.file-content {
width: 86vw;
position: relative;
.img-container {
img {
max-height: 100vh;
&:hover {
cursor: pointer;
}
}
}
.error {
background-color: #fff;
img {
width: 500px;
}
}
}
.close-btn {
position: absolute;
top: 12px;
right: 8px;
background-color: transparent;
border: none;
color: #fff;
&:hover {
color: red;
}
}
.rotate-left-btn {
position: absolute;
top: 12px;
right: 118px;
background-color: transparent;
border: none;
color: #fff;
}
.rotate-right-btn {
position: absolute;
top: 12px;
right: 68px;
background-color: transparent;
border: none;
color: #fff;
}
.left-btn {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
background-color: transparent;
border: none;
color: #fff;
}
.right-btn {
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
background-color: transparent;
border: none;
color: #fff;
}
.download-btn {
position: absolute;
bottom: 20px;
right: 20px;
}
.file-number {
position: absolute;
top: 16px;
left: 18px;
color: #fff;
}
}
</style>

5
src/components/file/upload.vue

@ -9,6 +9,7 @@
@success="handleSuccess" @success="handleSuccess"
@error="handleError" @error="handleError"
:show-file-list="false" :show-file-list="false"
:accept="accept"
class="mb-16" class="mb-16"
> >
<el-button <el-button
@ -40,6 +41,10 @@ const props = defineProps({
tips: { tips: {
type: String, type: String,
default: '' default: ''
},
accept: {
type: String,
default: '*'
} }
}); });

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

@ -32,6 +32,17 @@
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane name="comfort">
<template #label>
<el-badge :value="myComfortTotal" v-if="comforts.length">
<span class="tab-nav-title">我的抚慰</span>
</el-badge>
<span class="tab-nav-title" v-else>我的抚慰</span>
</template>
<div v-loading="comfortLoading" class="pt-20">
<home-work-my-comfort :data="comforts" @update="getComfortList" />
</div>
</el-tab-pane>
<el-tab-pane name="alarm"> <el-tab-pane name="alarm">
<template #label> <template #label>
<el-badge :value="myAlarmTotal" v-if="alarms.length"> <el-badge :value="myAlarmTotal" v-if="alarms.length">
@ -43,6 +54,7 @@
<home-work-my-alarm :data="alarms" @update="getAlarmList" /> <home-work-my-alarm :data="alarms" @update="getAlarmList" />
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</template> </template>
<script setup> <script setup>
@ -50,7 +62,9 @@ import { listTodos } from "@/api/work";
import { import {
alarmNotificationPageByTodo alarmNotificationPageByTodo
} from "@/api/work/alarm"; } from "@/api/work/alarm";
import {
listComfortTodos
} from "@/api/rightsComfort/comfort";
const activeName = "todo"; const activeName = "todo";
const myTodoTotal = ref(0) const myTodoTotal = ref(0)
const todos = ref([]) const todos = ref([])
@ -73,7 +87,7 @@ function getList() {
}); });
} }
const alarmLoading = ref(true) const alarmLoading = ref(false)
function getAlarmList() { function getAlarmList() {
alarmLoading.value = true alarmLoading.value = true
alarmNotificationPageByTodo({ alarmNotificationPageByTodo({
@ -86,9 +100,25 @@ function getAlarmList() {
}); });
} }
const myComfortTotal = ref(0)
const comfortLoading = ref(false)
const comforts = ref([])
function getComfortList() {
comfortLoading.value = true
listComfortTodos({
current: 1,
size: 100,
}).then((data) => {
comforts.value = data.records;
myComfortTotal.value = data.total
comfortLoading.value = false
});
}
onMounted(() => { onMounted(() => {
getList(); getList();
getAlarmList(); getAlarmList();
getComfortList();
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

105
src/components/home/work/my-comfort.vue

@ -0,0 +1,105 @@
<template>
<div class="table-container">
<el-table :data="data">
<el-table-column
label="抚慰编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column label="申请时间" prop="applyDate" width="160" />
<el-table-column label="事发时间" prop="happenTime" width="160" />
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column label="开户行">
<template #default="{ row }">
<span>{{ row.bankCard }}</span>
<span>{{ row.bankBranch }}</span>
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag
:type="
row.rpcStatus !== 'returned' ? 'primary' : 'danger'
"
v-if="row.rpcStatus"
>{{
getDictLable(dict.comfortStatus, row.rpcStatus)
}}</el-tag
>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button
link
type="primary"
@click="handleShow(row, false)"
v-if="row.rpcStatus !== 'returned'"
>立即处理</el-button
>
<template v-else>
<el-button
link
type="primary"
@click="handleShow(row, true)"
>查看</el-button
>
<!-- <el-button
link
type="primary"
@click="handleReSubmit(row)"
>重新提交</el-button
> -->
<el-button
link
type="danger"
v-if="row.rpcStatus === 'returned'"
@click="handleDelete(row)"
>删除</el-button
>
</template>
</template>
</el-table-column>
</el-table>
</div>
<comfort-dialog
v-model:show="show"
:id="activeRpcId"
:disabled="false"
@update="emit('update')"
/>
</template>
<script setup>
import { getDictLable } from "@/utils/util";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts([
"comfortStatus"
]);
defineProps({
data: {
type: Array,
default: [],
},
});
const emit = defineEmits(["update"]);
const show = ref(false);
const activeRpcId = ref('');
function handleShow(row) {
show.value = true;
activeRpcId.value = row.rpcId;
}
</script>
<style lang="scss" scoped>
</style>

8
src/components/negative/action-history.vue

@ -1,14 +1,12 @@
<template> <template>
<div class="flow"> <div class="flow" style="height: 100%">
<header class="flex between v-center flow-header" ref="flowHeaderRef"> <header class="flex between v-center flow-header" ref="flowHeaderRef">
<span> <span>
<span class="second mr-8">总耗时</span> <span class="second mr-8">总耗时</span>
<span style="color: var(--primary-color)">{{ <span style="color: var(--primary-color)">{{}}</span>
}}</span>
</span> </span>
</header> </header>
<el-scrollbar height="300"> <el-scrollbar max-height="calc(100% - 33px)">
<div class="flow-container"> <div class="flow-container">
<div v-for="(item, index) in actionHistory" :key="item.id"> <div v-for="(item, index) in actionHistory" :key="item.id">
<div class="mb-4 mt-4 flow-info"> <div class="mb-4 mt-4 flow-info">

161
src/components/negative/add.vue

@ -1,7 +1,13 @@
<template> <template>
<el-dialog title="问题下发" width="54vw" :lock-scroll="false" top="5vh"> <el-dialog
title="问题下发"
width="54vw"
:lock-scroll="false"
top="5vh"
style="margin-bottom: 0"
>
<el-scrollbar <el-scrollbar
height="75vh" height="78vh"
v-loading="loading" v-loading="loading"
element-loading-text="问题下发中..." element-loading-text="问题下发中..."
> >
@ -136,11 +142,6 @@
<el-form-item <el-form-item
label="涉嫌问题" label="涉嫌问题"
prop="involveProblem" prop="involveProblem"
:rules="{
required: true,
message: '请选择涉嫌问题',
trigger: ['blur'],
}"
> >
<el-select <el-select
v-model="form.involveProblem" v-model="form.involveProblem"
@ -271,6 +272,84 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-form-item
v-for="(item, index) in form.problems"
:key="index"
:label="`问题${index + 1}`"
>
<div class="flex between v-center" style="width: 100%">
<div class="flex">
<problem-type-select
style="width: 280px"
@change="
(node) =>
handleChangeProblem(node, item)
"
v-model="item.threeLevelCode"
/>
<div style="width: 140px" class="ml-8">
<el-form-item
label-position="top"
:prop="`problems.${index}.threeLevelContentOther`"
:rules="{
required: true,
message: '请输入',
trigger: ['blur'],
}"
style="margin-bottom: 0"
v-if="
item.threeLevelContent === '其他'
"
>
<el-input
placeholder="其他类型详细描述"
v-model="
item.threeLevelContentOther
"
/>
</el-form-item>
</div>
<div style="width: 170px;" class="text-nowrap ml-8">
<span>{{
item.oneLevelContent
? item.oneLevelContent + " / "
: ""
}}</span>
<span>{{
item.twoLevelContent
? item.twoLevelContent + " / "
: ""
}}</span>
<span>{{ item.threeLevelContent }}</span>
</div>
</div>
<el-button
@click="handleRemoveProblem(index)"
plain
type="danger"
size="small"
>
<template #icon>
<icon name="el-icon-Delete" />
</template>
删除问题
</el-button>
</div>
</el-form-item>
<div class="flex center mb-10">
<el-button
@click="handleAddProblem()"
plain
type="primary"
size="small"
>
<template #icon>
<icon name="el-icon-Plus" />
</template>
添加问题
</el-button>
</div>
<el-form-item <el-form-item
label="事情简要描述" label="事情简要描述"
prop="thingDesc" prop="thingDesc"
@ -319,13 +398,25 @@
/> />
</el-select> </el-select>
<div class="tips mt-10"> <div class="tips mt-10">
<p>如主办层级 市局主办 则由<span :danger="form.hostLevel === HostLevel.FIRST">督察支队</span>办理</p>
<p> <p>
如主办层级为 如主办层级 市局主办 则由<span
二级机构主办则由<span :danger="form.hostLevel === HostLevel.SECOND">督察部门</span>办理可进一步下发 :danger="form.hostLevel === HostLevel.FIRST"
>督察支队</span
>办理
</p>
<p>
如主办层级为 二级机构主办则由<span
:danger="
form.hostLevel === HostLevel.SECOND
"
>督察部门</span
>办理可进一步下发
</p> </p>
<p> <p>
如主办层级为 三级机构主办则由<span :danger="form.hostLevel === HostLevel.THREE">所队</span>办理 如主办层级为 三级机构主办则由<span
:danger="form.hostLevel === HostLevel.THREE"
>所队</span
>办理
</p> </p>
</div> </div>
</el-form-item> </el-form-item>
@ -412,7 +503,12 @@
trigger: ['blur'], trigger: ['blur'],
}" }"
> >
<el-radio-group v-model="form.approvalFlow"> <el-radio-group
v-model="form.approvalFlow"
v-if="
userStore.user.roleCodes.includes('admin_1')
"
>
<el-radio <el-radio
v-for="item in dict.approvalFlow" v-for="item in dict.approvalFlow"
:key="item.dictCode" :key="item.dictCode"
@ -423,8 +519,19 @@
}}</el-radio }}</el-radio
> >
</el-radio-group> </el-radio-group>
<el-radio-group v-model="form.approvalFlow" v-else>
<el-radio value="2"
>二级审批(所队一>二级机构)</el-radio
>
</el-radio-group>
<div class="tips mt-10"> <div class="tips mt-10">
<p> <p
v-if="
userStore.user.roleCodes.includes(
'admin_1'
)
"
>
三级审核 在问题提交办结时需经过所队>二级机构>市局三级审核通过后方可办结 三级审核 在问题提交办结时需经过所队>二级机构>市局三级审核通过后方可办结
</p> </p>
<p> <p>
@ -461,7 +568,10 @@ import feedback from "@/utils/feedback";
import { addNegative, generateOriginId } from "@/api/work/negative"; import { addNegative, generateOriginId } from "@/api/work/negative";
import { secondList, listByFirstHost } from "@/api/system/depart"; import { secondList, listByFirstHost } from "@/api/system/depart";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
import { disabledDate } from '@/utils/util' import { disabledDate } from "@/utils/util";
import useUserStore from "@/stores/modules/user";
const userStore = useUserStore();
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts([ const dict = catchStore.getDicts([
@ -487,7 +597,8 @@ const form = ref({
thingFiles: [], thingFiles: [],
hostLevel: HostLevel.THREE, hostLevel: HostLevel.THREE,
timeLimit: TimeLimit.WORK_137, timeLimit: TimeLimit.WORK_137,
approvalFlow: ApprovalFlow.SECOND approvalFlow: ApprovalFlow.SECOND,
problems: [],
}); });
watch( watch(
@ -524,7 +635,7 @@ async function handleAddNegative() {
thingFiles: [], thingFiles: [],
hostLevel: HostLevel.THREE, hostLevel: HostLevel.THREE,
timeLimit: TimeLimit.WORK_137, timeLimit: TimeLimit.WORK_137,
approvalFlow: ApprovalFlow.SECOND approvalFlow: ApprovalFlow.SECOND,
}; };
feedback.msgSuccess("下发成功"); feedback.msgSuccess("下发成功");
emit("close"); emit("close");
@ -566,14 +677,30 @@ function handleChangeHostLevel(val) {
} }
} }
function handleAddProblem() {
form.value.problems.push({});
}
function handleRemoveProblem(index) {
form.value.problems.splice(index, 1);
}
function handleChangeProblem(node, problem) {
if (node.level === 3) {
problem.threeLevelContent = node.label;
problem.oneLevelCode = node.parent.parent.key;
problem.oneLevelContent = node.parent.parent.label;
problem.twoLevelCode = node.parent.key;
problem.twoLevelContent = node.parent.label;
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.add-negation-container { .add-negation-container {
padding: 0 60px; padding: 0 60px;
} }
.tips { .tips {
[danger=true] { [danger="true"] {
color: var(--danger-color); color: var(--danger-color);
} }
} }

2
src/components/negative/apply-completion.vue

@ -10,8 +10,6 @@
<h3>{{ negative.handleSecondDepartName || '二级机构' }} 市局专班</h3> <h3>{{ negative.handleSecondDepartName || '二级机构' }} 市局专班</h3>
<p style="margin-bottom: 40px">逐级审核通过后即可完成办理</p> <p style="margin-bottom: 40px">逐级审核通过后即可完成办理</p>
</template> </template>
</div> </div>
<footer class="flex end"> <footer class="flex end">

2
src/components/negative/apply-countersign.vue

@ -29,7 +29,7 @@
> >
<div style="min-height: 200px"> <div style="min-height: 200px">
<div class="flex gap-20 mb-10" v-for="(item, index) in formData.countersignDeparts" :key="index"> <div class="flex gap-20 mb-10" v-for="(item, index) in formData.countersignDeparts" :key="index">
<div style="width: 280px"> <div style="width: 280px" class="mr-10">
<depart-tree-select v-model="item.id" /> <depart-tree-select v-model="item.id" />
</div> </div>
<el-button type="primary" plain v-if="index === 0" @click="handleAddDepart"> <el-button type="primary" plain v-if="index === 0" @click="handleAddDepart">

5
src/components/negative/apply-extension.vue

@ -2,9 +2,10 @@
<el-dialog width="50vw" title="申请延期" v-model="show"> <el-dialog width="50vw" title="申请延期" v-model="show">
<div> <div>
<p> <p>
全流程可延期的总时长不超过{{ negative.maxExtensionDuration }}(中间包括节假日)申请延期需经过 全流程可延期的总时长不超过{{ negative.maxExtensionDuration }}(中间包括节假日)申请延期需经过
</p> </p>
<h3>二级专班 市局</h3> <h3 v-if="negative.approvalFlow === '3'">{{ negative.handleSecondDepartName }}专班 市局</h3>
<h3 v-else>{{ negative.handleSecondDepartName }}专班</h3>
<p> <p>
审批通过之后才能正式生效在申请延期过程中三级机构仍然可以按照正常流程进行信件的处理如果已提交信件办结申请并通过市局专班的审批则申请延期的流程自动结束 审批通过之后才能正式生效在申请延期过程中三级机构仍然可以按照正常流程进行信件的处理如果已提交信件办结申请并通过市局专班的审批则申请延期的流程自动结束
</p> </p>

26
src/components/negative/description.vue

@ -2,13 +2,17 @@
<div class="info-container"> <div class="info-container">
<h3>问题信息</h3> <h3>问题信息</h3>
<div class="row"> <div class="row">
<div class="col col-6"> <div class="col col-12">
<label>样本源头编号</label> <label>样本源头编号</label>
<span>{{ negative.originId }}</span> <span>{{ negative.originId }}</span>
</div> </div>
<div class="col col-12">
<label>案件/警情编号</label>
<span>{{ negative.caseNumber || '/' }}</span>
</div>
<div class="col col-6"> <div class="col col-6">
<label>问题发现时间</label> <label>问题发现时间</label>
<span>{{ negative.discoveryTime }}</span> <span>{{ negative.discoveryTime || '/' }}</span>
</div> </div>
<div class="col col-6" v-if="negative.happenTime"> <div class="col col-6" v-if="negative.happenTime">
<label>问题发生时间</label> <label>问题发生时间</label>
@ -18,8 +22,6 @@
<label>问题来源</label> <label>问题来源</label>
<span>{{ negative.problemSources }}</span> <span>{{ negative.problemSources }}</span>
</div> </div>
</div>
<div class="row">
<div class="col col-6" v-if="negative.responderName"> <div class="col col-6" v-if="negative.responderName">
<label>投诉反映人</label> <label>投诉反映人</label>
<span>{{ negative.responderName }}</span> <span>{{ negative.responderName }}</span>
@ -28,8 +30,6 @@
<label>联系电话</label> <label>联系电话</label>
<span>{{ negative.contactPhone }}</span> <span>{{ negative.contactPhone }}</span>
</div> </div>
</div>
<div class="row">
<div class="col col-6" v-if="negative.specialSupervision"> <div class="col col-6" v-if="negative.specialSupervision">
<label>专项督察</label> <label>专项督察</label>
<span>{{ getDictLable(dict.specialSupervision, negative.specialSupervision) }}</span> <span>{{ getDictLable(dict.specialSupervision, negative.specialSupervision) }}</span>
@ -42,24 +42,22 @@
<label>业务类别</label> <label>业务类别</label>
<span>{{ negative.businessTypeName }}</span> <span>{{ negative.businessTypeName }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-6" v-if="negative.policeTypeName">
<label>涉及警种</label> <label>涉及警种</label>
<span>{{ negative.policeTypeName || '/' }}</span> <span>{{ negative.policeTypeName }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-12">
<label>涉嫌问题</label> <label>涉嫌问题</label>
<span>{{ getInvolveProblem(negative.involveProblem, dict.suspectProblem) || '/' }}</span> <span>{{ getInvolveProblem(negative.involveProblem, dict.suspectProblem) || '/' }}</span>
</div> </div>
</div>
<div class="row">
<div class="col col-12" v-if="negative.caseNumber">
<label>案件/警情编号</label>
<span>{{ negative.caseNumber }}</span>
</div>
<div class="col col-12"> <div class="col col-12">
<label>涉及单位</label> <label>涉及单位</label>
<span>{{ negative.involveDepartName || '/' }}</span> <span>{{ negative.involveDepartName || '/' }}</span>
</div> </div>
<div class="col col-6">
<label>创建时间</label>
<span>{{ negative.crtTime }}</span>
</div>
</div> </div>
<div> <div>
<div class="text-primary mt-10">事情简要描述</div> <div class="text-primary mt-10">事情简要描述</div>

96
src/components/negative/dialog.vue

@ -71,7 +71,8 @@
<el-row style="height: 100%"> <el-row style="height: 100%">
<el-col :span="5" style="height: 100%"> <el-col :span="5" style="height: 100%">
<div ref="leftContainerRef" class="left-container h100"> <div ref="leftContainerRef" class="left-container h100">
<template <div
ref="countdownContainerRef"
v-if=" v-if="
negative.flowKey !== negative.flowKey !==
FlowNodeEnum.FIRST_DISTRIBUTE && FlowNodeEnum.FIRST_DISTRIBUTE &&
@ -84,37 +85,51 @@
:max-time="maxDuration" :max-time="maxDuration"
:extensionDays="negative.extensionDays" :extensionDays="negative.extensionDays"
/> />
</template> </div>
<div class="row"> <div class="row" ref="leftRowRef">
<div class="col col-24" style="--label-width: 60px"> <div
class="col col-24"
style="--label-width: 60px"
v-if="negative.timeLimit"
>
<label>办理时限</label> <label>办理时限</label>
<span>{{ <span>{{
getDictLable( getDictLable(
dict.timeLimit, dict.timeLimit,
negative.timeLimit negative.timeLimit
) || "/" )
}}</span> }}</span>
</div> </div>
<div class="col col-24" style="--label-width: 60px"> <div
class="col col-24"
style="--label-width: 60px"
v-if="negative.hostLevel"
>
<label>主办层级</label> <label>主办层级</label>
<span>{{ <span>{{
getDictLable( getDictLable(
dict.hostLevel, dict.hostLevel,
negative.hostLevel negative.hostLevel
) || "/" )
}}</span> }}</span>
</div> </div>
<div class="col col-24" style="--label-width: 60px"> <div
class="col col-24"
style="--label-width: 60px"
v-if="negative.approvalFlow"
>
<label>审批流程</label> <label>审批流程</label>
<span>{{ <span>{{
getDictLable( getDictLable(
dict.approvalFlow, dict.approvalFlow,
negative.approvalFlow negative.approvalFlow
) || "/" )
}}</span> }}</span>
</div> </div>
</div> </div>
<negative-action-history /> <div ref="actionHistoryRef">
<negative-action-history />
</div>
</div> </div>
</el-col> </el-col>
<el-col :span="19" style="height: 100%"> <el-col :span="19" style="height: 100%">
@ -306,17 +321,19 @@
> >
<el-tooltip <el-tooltip
effect="dark" effect="dark"
:content="`该问题目前正在${negative.currentProcessingObject}等待延期审批,请延期审批通过后再进行提交!`" :content="`${negative.currentProcessingObject}正在审理您提交的延期审批,请耐心等待审批通过后再操作!`"
raw-content raw-content
placement="top" placement="top"
> >
<el-button <span class="ml-10">
size="large" <el-button
:type="item.buttonType" size="large"
:plain="item.plain" :type="item.buttonType"
:disabled="true" :plain="item.plain"
>{{ item.buttonLabel }}</el-button :disabled="true"
> >{{ item.buttonLabel }}</el-button
>
</span>
</el-tooltip> </el-tooltip>
</template> </template>
<el-button <el-button
@ -393,6 +410,7 @@ import { getComponents } from "@/utils/flow";
import { getDictLable } from "@/utils/util"; import { getDictLable } from "@/utils/util";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
import { nextTick, onMounted } from "vue";
const dict = useCatchStore().getDicts([ const dict = useCatchStore().getDicts([
"processingStatus", "processingStatus",
@ -558,14 +576,6 @@ function spotCheck() {
} }
const dialogRef = ref(); const dialogRef = ref();
watch(
() => dialogRef.value?.visible,
(val) => {
if (!val) {
spotCheckEditFlag.value = false;
}
}
);
const formData = ref({}); const formData = ref({});
const formRef = ref(); const formRef = ref();
@ -599,6 +609,40 @@ async function handleUpdateVerify() {
defineExpose({ defineExpose({
spotCheck, spotCheck,
}); });
//
const leftContainerRef = ref();
const countdownContainerRef = ref();
const leftRowRef = ref();
const actionHistoryRef = ref();
watch(
() => dialogRef.value?.visible,
(val) => {
if (!val) {
spotCheckEditFlag.value = false;
}
}
);
watch(loading, (val) => {
if (!val) {
nextTick(() => {
console.log("nextTick", [leftContainerRef.value.offsetHeight]);
actionHistoryRef.value.style.height = `${
leftContainerRef.value.offsetHeight -
(countdownContainerRef.value?.offsetHeight || 0) -
leftRowRef.value.offsetHeight
}px`;
console.log(
`${
leftContainerRef.value.offsetHeight -
(countdownContainerRef.value?.offsetHeight || 0) -
leftRowRef.value.offsetHeight
}px`
);
});
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dialog-header { .dialog-header {

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

@ -40,6 +40,23 @@
<span>{{ negative.rectifyDesc }}</span> <span>{{ negative.rectifyDesc }}</span>
</div> </div>
</div> </div>
<div class="row" v-if="negative.unrectifyReason">
<div class="col col-24">
<label>问题未整改原因</label>
<span>{{ negative.unrectifyReason }}</span>
</div>
</div>
<div class="row" v-if="negative.handlePolices.length > 0">
<div class="col col-24">
<label>经办人</label>
<span>
<div v-for="item in negative.handlePolices" :key="item" class="mr-20">
<span class="mr-8">{{ item.name }}</span>
<span class="text-primary">{{ item.empNo }}</span>
</div>
</span>
</div>
</div>
</el-collapse-item> </el-collapse-item>
<el-collapse-item <el-collapse-item
v-for="(blame, index) in negative.blames.filter( v-for="(blame, index) in negative.blames.filter(
@ -52,7 +69,10 @@
<div class="row"> <div class="row">
<div class="col col-6"> <div class="col col-6">
<label>涉及人员姓名</label> <label>涉及人员姓名</label>
<span>{{ blame.blameName }} {{ blame.blameEmpNo }}</span> <span>
<span>{{ blame.blameName }}</span>
<span class="text-primary ml-10">{{ blame.blameEmpNo }}</span>
</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>身份证</label> <label>身份证</label>
@ -132,11 +152,12 @@
<div class="row" style="background: #f5f5f5"> <div class="row" style="background: #f5f5f5">
<div class="col col-6"> <div class="col col-6">
<label>涉及领导姓名</label> <label>涉及领导姓名</label>
<span>{{ blame.leadName }} {{ blame.leadEmpNo }}</span> <span v-if="blame.leadName">{{ blame.leadName }} {{ blame.leadEmpNo }}</span>
<span v-else>/</span>
</div> </div>
<div class="col col-6"> <div class="col col-6">
<label>身份证</label> <label>身份证</label>
<span>{{ blame.leadIdCode }}</span> <span>{{ blame.leadIdCode || '/' }}</span>
</div> </div>
<div class="col col-6" v-if="blame.leadResponsibilityTypeName"> <div class="col col-6" v-if="blame.leadResponsibilityTypeName">

74
src/components/negative/verify.vue

@ -455,7 +455,9 @@
<div <div
class="flex center" class="flex center"
style="width: 100%" style="width: 100%"
v-if="item.problems.length === 0" v-if="
!item.problems || item.problems.length === 0
"
> >
<el-button <el-button
@click="handleAddProblem(item)" @click="handleAddProblem(item)"
@ -518,7 +520,7 @@
trigger: ['blur'], trigger: ['blur'],
}" }"
> >
<div class="flex gap"> <div class="flex gap v-center">
<el-radio-group <el-radio-group
v-model="item.subjectiveAspectCode" v-model="item.subjectiveAspectCode"
@change=" @change="
@ -547,6 +549,8 @@
item.subjectiveAspectCode === item.subjectiveAspectCode ===
SubjectiveAspect.OTHER SubjectiveAspect.OTHER
" "
style="margin-bottom: 0"
class="ml-20"
> >
<el-input <el-input
v-model=" v-model="
@ -1123,10 +1127,28 @@
" "
> >
<el-radio <el-radio
v-for="item in dict.superviseMeasures" v-for="dictItem in dict.superviseMeasures"
:key="item.dictCode" :key="dictItem.dictCode"
:value="item.dictValue" :value="dictItem.dictValue"
>{{ item.dictLabel }} @click.native.prevent="
() => {
if (
item.superviseMeasuresCode ===
dictItem.dictValue
) {
item.superviseMeasuresCode =
'';
item.superviseMeasuresName =
'';
} else {
item.superviseMeasuresCode =
dictItem.dictValue;
item.superviseMeasuresName =
dictItem.dictLabel;
}
}
"
>{{ dictItem.dictLabel }}
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
@ -1244,6 +1266,26 @@
</el-button> </el-button>
</div> </div>
</div> </div>
<div
class="flex center"
style="width: 100%"
v-if="
!item.problems ||
item.problems.length === 0
"
>
<el-button
@click="handleAddProblem(item)"
plain
type="primary"
size="small"
>
<template #icon>
<icon name="el-icon-Plus" />
</template>
添加问题
</el-button>
</div>
</el-form-item> </el-form-item>
</div> </div>
</el-form-item> </el-form-item>
@ -1549,7 +1591,7 @@ function handleAddPersonal() {
}); });
if (form.value.blameLeaders.length == 0) { if (form.value.blameLeaders.length == 0) {
handleAddBlameLeader() handleAddBlameLeader();
} }
} }
@ -1558,6 +1600,9 @@ function handleRemovePersonal(item) {
} }
function handleAddProblem(blame) { function handleAddProblem(blame) {
if (!blame.problems) {
blame.problems = [];
}
blame.problems.push({}); blame.problems.push({});
} }
@ -1630,6 +1675,10 @@ watch(
); );
function handleChangeCheckStatus(val, item) { function handleChangeCheckStatus(val, item) {
if (val === "4") {
form.value.checkStatusName = "无法办理";
return;
}
form.value.checkStatusName = dict.inspectCase.filter( form.value.checkStatusName = dict.inspectCase.filter(
(item) => item.dictValue === val (item) => item.dictValue === val
)[0].dictLabel; )[0].dictLabel;
@ -1690,6 +1739,17 @@ function handleChangeResultCode(item) {
} }
} }
function handleChangeLeadResultCode(item) {
if (item.leadHandleResultCode && item.leadHandleResultCode.length > 0) {
item.leadHandleResultName = dict.handleResult
.filter((obj) => item.leadHandleResultCode.includes(obj.dictValue))
.map((obj) => obj.dictLabel)
.join("、");
} else {
item.leadHandleResultName = "";
}
}
function handleChangeDepartResultCode(item) { function handleChangeDepartResultCode(item) {
if (item.handleResultCode && item.handleResultCode.length > 0) { if (item.handleResultCode && item.handleResultCode.length > 0) {
item.handleResultName = dict.departHandleResult item.handleResultName = dict.departHandleResult

1
src/components/negativeInfo/depart-dialog.vue

@ -1,7 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="单位问题详情" title="单位问题详情"
v-model="show"
width="85vw" width="85vw"
top="1vh" top="1vh"
style="margin: 1vh auto" style="margin: 1vh auto"

7
src/components/query-select.vue

@ -67,7 +67,12 @@ function handleCheck(val) {
} }
} }
.query-check { .query-check {
gap: 4px; >* {
margin-right: 4px;
&:last-child {
margin-right: 0;
}
}
span { span {
padding: 2px 4px; padding: 2px 4px;
border: 1px solid transparent; border: 1px solid transparent;

60
src/components/video-play.vue

@ -0,0 +1,60 @@
<template>
<div ref="playerRef" class="video-container"></div>
</template>
<script setup>
import { nextTick } from "vue";
const props = defineProps({
url: {
type: String,
default: ''
},
showOperateBtns: {
type: Boolean,
default: true
}
})
const playerRef = ref();
let jessibucaPlayer;
onMounted(() => {
//
nextTick(() => {
playerRef.value.style.height = playerRef.value.scrollWidth * 0.6 + 'px'
})
let operateBtns = {}
if (props.showOperateBtns) {
operateBtns = {
screenshot: true, //
fullscreen: true, //
play: true, //
audio: true, //
record: false, //
}
}
jessibucaPlayer = new Jessibuca({
container: playerRef.value,
isFlv: true, // 使flv
showBandwidth: false, // 使
isResize: false,
operateBtns,
loadingText: "加载中...",
});
if (props.url) {
jessibucaPlayer.play(props.url);
}
});
watch(() => props.url, (url) => {
if (url) {
jessibucaPlayer.play(url);
}
})
</script>
<style lang="scss">
.video-container {
background-color: #0d0e1b;
}
</style>

20
src/layout/components/Aside.vue

@ -51,12 +51,12 @@
</a> </a>
</nav> </nav>
</el-scrollbar> </el-scrollbar>
<button <!-- <button
class="flex center v-center pointer expand-btn" class="flex center v-center pointer expand-btn"
@click="handleAsideCollapse" @click="handleAsideCollapse"
> >
<!-- <icon name="el-icon-ArrowLeftBold" :size="58" /> --> <icon name="el-icon-ArrowLeftBold" :size="58" />
</button> </button> -->
</aside> </aside>
</template> </template>
<script setup> <script setup>
@ -115,7 +115,12 @@ aside {
transition: width height 0.6s; transition: width height 0.6s;
} }
.menu-item { .menu-item {
gap: 20px; > * {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
height: 56px; height: 56px;
padding: 0 18px; padding: 0 18px;
display: flex; display: flex;
@ -127,7 +132,12 @@ aside {
color: #fff; color: #fff;
} }
section { section {
gap: 16px; > * {
margin-right: 16px;
&:last-child {
margin-right: 0;
}
}
} }
.el-button { .el-button {
color: #656fac; color: #656fac;

4
src/router/routes.ts

@ -95,10 +95,6 @@ export const routes = [
path: '/datav/subOneRightsComfort', path: '/datav/subOneRightsComfort',
component: () => import('@/views/datav/subonedatav/SubOneRightsComfort.vue'), component: () => import('@/views/datav/subonedatav/SubOneRightsComfort.vue'),
}, },
{
path: '/work/verifySubmit',
component: () => import('@/views/work/VerifySubmit.vue'),
},
{ {
path: '/system/Operating', path: '/system/Operating',
component: () => import('@/views/system/Operating.vue'), component: () => import('@/views/system/Operating.vue'),

83
src/style/public.scss

@ -53,7 +53,7 @@ img {
max-width: 100%; max-width: 100%;
} }
svg + span { svg+span {
margin-left: .5em; margin-left: .5em;
} }
@ -111,28 +111,59 @@ svg + span {
.flex.gap-4, .flex.gap-4,
.flex-inline.gap-4 { .flex-inline.gap-4 {
gap: 4px; >* {
margin-right: 4px;
&:last-child {
margin-right: 0;
}
}
} }
.flex.gap, .flex.gap,
.flex-inline.gap { .flex-inline.gap {
gap: 8px; >* {
margin-right: 8px;
&:last-child {
margin-right: 0;
}
}
} }
.flex.gap-10 { .flex.gap-10 {
gap: 10px; >* {
margin-right: 10px;
&:last-child {
margin-right: 0;
}
}
} }
.flex.gap-12 { .flex.gap-12 {
gap: 12px; >* {
margin-right: 12px;
&:last-child {
margin-right: 0;
}
}
} }
.flex.gap-16 { .flex.gap-16 {
gap: 16px; margin-right: 16px;
&:last-child {
margin-right: 0;
}
} }
.flex.gap-20 { .flex.gap-20 {
gap: 20px; margin-right: 20px;
&:last-child {
margin-right: 0;
}
} }
.text-small { .text-small {
@ -357,7 +388,8 @@ svg + span {
--gap-width: 10px; --gap-width: 10px;
display: flex; display: flex;
gap: var(--gap-width);
&.col-4 { &.col-4 {
width: 16.6%; width: 16.6%;
} }
@ -386,9 +418,10 @@ svg + span {
width: var(--label-width); width: var(--label-width);
text-align: right; text-align: right;
color: #999; color: #999;
margin-right: var(--gap-width);
} }
> span { >span {
width: calc(100% - var(--label-width) - var(--gap-width)); width: calc(100% - var(--label-width) - var(--gap-width));
color: #333; color: #333;
} }
@ -502,25 +535,33 @@ svg + span {
} }
.form-row { .form-row {
margin-bottom: 18px; margin-bottom: 8px;
font-size: 14px; font-size: 14px;
label { label {
width: 120px; width: 120px;
line-height: 32px; line-height: 32px;
padding-right: 12px; padding-right: 12px;
box-sizing: border-box; box-sizing: border-box;
text-align: right; text-align: right;
& + * {
width: calc(100% - 126px); &+* {
} width: calc(100% - 126px);
}
} }
.btn-box { .btn-box {
width: 70px; width: 70px;
} }
.el-form-item { .el-form-item {
margin-bottom: 0; margin-bottom: 0;
} }
} }
.query-box { .query-box {
gap: 10px 20px; > * {
margin-right: 10px;
margin-bottom: 10px;
}
} }

4
src/utils/feedback.ts

@ -40,8 +40,8 @@ export class Feedback {
}) })
} }
// 弹出提示 // 弹出提示
alert(msg: string) { alert(msg: string, title: string) {
ElMessageBox.alert(msg, '系统提示') ElMessageBox.alert(msg, title || '系统提示')
} }
// 错误提示 // 错误提示
alertError(msg: string) { alertError(msg: string) {

347
src/views/books/Audit.vue

@ -0,0 +1,347 @@
<template>
<div class="container">
<header>
<el-form :label-width="120">
<el-row>
<el-col :span="6">
<el-form-item label="问题发现时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="问题录入时间">
<date-time-range-picker-ext
v-model="query.crtTime"
/>
</el-form-item>
</el-col>
</el-row>
<div class="form-row flex">
<label class="text-center">问题信息</label>
<div class="flex wrap query-box">
<el-input
placeholder="问题编号 / 样本源头编号"
v-model="query.originId"
clearable
style="width: 200px"
/>
<el-input
placeholder="涉及案件 / 警情编号"
v-model="query.caseNumber"
clearable
style="width: 200px"
/>
<el-input
placeholder="事情简要描述"
v-model="query.thingDesc"
clearable
style="width: 260px"
/>
<el-select
style="width: 146px"
placeholder="业务类别"
clearable
v-model="query.businessTypeCode"
>
<el-option
v-for="item in dict.businessType"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<el-tree-select
:data="dictProblemSources"
:props="{ value: 'id' }"
node-key="id"
v-model="query.problemSourcesCode"
clearable
filterable
multiple
collapse-tags
style="width: 200px"
placeholder="问题来源"
/>
</div>
</div>
<div class="form-row flex">
<label class="text-center">核查情况</label>
<div class="flex wrap query-box">
<div style="width: 200px">
<depart-tree-select
v-model="query.involveDepartId"
placeholder="涉及单位"
/>
</div>
<div style="width: 200px">
<depart-tree-select
v-model="query.handleDepartId"
placeholder="办理单位"
/>
</div>
<el-select
style="width: 120px"
placeholder="是否属实"
clearable
v-model="query.checkStatus"
>
<el-option
v-for="item in dict.inspectCase"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="是否整改"
clearable
v-model="query.isRectifyCode"
>
<el-option
v-for="item in dict.isRectify"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.blameKey"
style="width: 90px"
@change="delete query.blameValue"
>
<el-option value="name" label="姓名" />
<el-option value="empNo" label="警号" />
<el-option value="idCode" label="身份证" />
</el-select>
<el-input
placeholder="涉及人员"
v-model="query.blameValue"
clearable
style="width: 190px"
/>
</div>
</div>
</div>
<div class="form-row flex">
<label class="text-center">其他选项</label>
<div class="flex wrap query-box">
<el-select
style="width: 200px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="办理状态"
clearable
v-model="query.processingStatus"
multiple
>
<el-option
v-for="item in dict.processingStatus"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<el-select
style="width: 160px"
placeholder="办理中是否超时"
clearable
v-model="query.handleTimeoutFlag"
>
<el-option label="未超时" :value="false" />
<el-option label="已超时" :value="true" />
</el-select>
<el-select
style="width: 140px"
placeholder="办结是否超时"
clearable
v-model="query.timeoutFlag"
>
<el-option label="办结未超时" :value="false" />
<el-option label="办结超时" :value="true" />
</el-select>
<el-select
style="width: 120px"
placeholder="申请延期"
clearable
v-model="query.extensionFlag"
>
<el-option label="已申请" :value="true" />
<el-option label="未申请" :value="false" />
</el-select>
</div>
</div>
</el-form>
<div class="flex between mt-20 mb-26">
<el-button type="primary" @click="handleExport"
>数据导出
</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="businessTypeName"
width="140"
/>
<el-table-column
label="问题来源"
prop="problemSources"
width="160"
/>
<el-table-column
label="问题发现时间"
prop="discoveryTime"
width="160"
/>
<el-table-column
label="案件/警情编号"
prop="caseNumber"
width="160"
/>
<el-table-column
label="具体内容"
prop="thingDesc"
show-overflow-tooltip
/>
<el-table-column
label="整改情况"
prop="rectifyDesc"
show-overflow-tooltip
/>
<el-table-column
label="涉及单位"
prop="involveDepartName"
width="180"
/>
<el-table-column label="办理单位" show-overflow-tooltip>
<template #default="{ row }">
<span
>{{ row.handleSecondDepartName
}}{{ row.handleThreeDepartName }}</span
>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleAction(row)"
>详情</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>
<negative-dialog
v-model="show"
:id="activeNegativeId"
@close="show = false"
/>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
import { ProblemSources } from "@/enums/dictEnums";
import feedback from "@/utils/feedback";
import { getDictLable } from "@/utils/util";
import useCatchStore from "@/stores/modules/catch";
import { listNegativeAudit } from "@/api/books.ts";
const catchStore = useCatchStore();
const flowNodes = catchStore.getFlowNodes();
const dictProblemSources = catchStore.getDictProblemSources();
const dict = catchStore.getDicts([
"inspectCase",
"businessType",
"processingStatus",
"isRectify"
]);
const query = ref({
size: 10,
current: 1,
blameKey: "name",
});
const list = ref([]);
const total = ref(0);
function getList() {
listNegativeAudit(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
size: 10,
current: 1,
blameKey: "name",
};
getList();
}
getList();
function handleExport() {
window.open(
`${BASE_PATH}/negative/books/export/audit?` +
new URLSearchParams(query.value).toString()
);
}
const show = ref(false);
const activeNegativeId = ref("");
function handleAction(row) {
show.value = true;
activeNegativeId.value = row.id;
}
</script>
<style lang="scss" scoped>
</style>

3
src/views/books/Gabxf.vue

@ -2,9 +2,6 @@
<div class="container"> <div class="container">
<header> <header>
<el-form :label-width="80"> <el-form :label-width="80">
<el-row>
<el-col :span="6"> </el-col>
</el-row>
<div class="form-row flex"> <div class="form-row flex">
<label class="text-center">基本信息</label> <label class="text-center">基本信息</label>
<div class="flex wrap query-box"> <div class="flex wrap query-box">

185
src/views/books/Mail12337.vue

@ -1,9 +1,192 @@
<template> <template>
<div class="container">
<header>
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="投诉人">
<div class="flex gap">
<el-select
v-model="query.responderKey"
style="width: 160px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="请输入"
v-model="query.responderValue"
clearable
/>
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="登记时间">
<date-time-range-picker-ext
v-model="query.discoverTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="具体内容">
<el-input
placeholder="请输入"
v-model="query.thingDesc"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="mb-25 flex between">
<div>
<el-button type="primary" @click="handleExport"
>数据导出
</el-button>
</div>
<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="onlyId"
show-overflow-tooltip
width="180"
/>
<el-table-column
label="投诉渠道"
prop="letterSource"
width="120"
/>
<el-table-column
label="登记时间"
prop="discoverTime"
width="150"
/>
<el-table-column label="投诉人" prop="name" width="90" />
<el-table-column label="电话" prop="phone" width="116" />
<el-table-column label="被投诉机构" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.secondDepartName }}</span>
<span>{{ row.thirdDepartName }}</span>
</template>
</el-table-column>
<el-table-column
label="具体内容"
prop="wjwfProject"
show-overflow-tooltip
/>
<el-table-column
label="是否属实"
prop="checkStatusName"
width="120"
/>
<el-table-column
label="核查简要情况"
prop="checkStatusDesc"
show-overflow-tooltip
/>
<el-table-column label="操作" width="120">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleAction(row)"
:disabled="!row.id"
>详情</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>
<negative-dialog
v-model="show"
:id="activeNegativeId"
@close="show = false"
/>
</template> </template>
<script setup> <script setup>
import { BASE_PATH } from "@/api/request";
import { ProblemSources } from "@/enums/dictEnums";
import feedback from "@/utils/feedback";
import { getDictLable } from "@/utils/util";
import useCatchStore from "@/stores/modules/catch";
import { listPetitionComplaint12337Books } from "@/api/data/petition12337.ts";
const catchStore = useCatchStore();
const dict = catchStore.getDicts(["distributionState", "inspectCase"]);
const query = ref({
size: 10,
current: 1,
responderKey: "name",
});
const list = ref([]);
const total = ref(0);
function getList() {
listPetitionComplaint12337Books(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
size: 10,
current: 1,
responderKey: "name",
};
getList();
}
getList();
function handleExport() {
window.open(
`${BASE_PATH}/negative/books/export/mail12337?` +
new URLSearchParams(query.value).toString()
);
}
const show = ref(false);
const activeNegativeId = ref("");
function handleAction(row) {
show.value = true;
activeNegativeId.value = row.id;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
</style> </style>

769
src/views/data/Ajhc.vue

@ -1,418 +1,410 @@
<template> <template>
<div class="container"> <div class="container">
<header> <header>
<el-form :label-width="114"> <el-form :label-width="114">
<el-row> <el-row>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="案件编号"> <el-form-item label="案件编号">
<el-input <el-input
placeholder="请输入" placeholder="请输入"
v-model="query.originId" v-model="query.originId"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="投诉人"> <el-form-item label="投诉人">
<div class="flex gap"> <div class="flex gap">
<el-select <el-select
v-model="query.responderKey" v-model="query.responderKey"
style="width: 160px" style="width: 160px"
@change="delete query.responderValue" @change="delete query.responderValue"
> >
<el-option value="name" label="姓名"/> <el-option value="name" label="姓名" />
<el-option value="phone" label="电话"/> <el-option value="phone" label="电话" />
</el-select> </el-select>
<el-input <el-input
placeholder="请输入" placeholder="请输入"
v-model="query.responderValue" v-model="query.responderValue"
clearable clearable
/>
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label=" 受理时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="具体内容">
<el-input
placeholder="请输入"
v-model="query.thingDesc"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分发状态">
<el-select
v-model="query.distributionState"
clearable
>
<el-option
v-for="item in dict.distributionState"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="是否属实">
<el-select clearable v-model="query.checkStatus">
<el-option
v-for="item in dict.inspectCase"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="mb-25 flex between">
<div>
<el-button type="primary" @click="show = true"
>数据导入
</el-button>
<el-badge
:value="distributeList.length"
class="ml-10"
v-if="distributeList.length"
>
<el-button
type="primary"
@click="distributeListShow = true"
>问题下发
</el-button>
</el-badge>
</div>
<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="originId"
show-overflow-tooltip
/> />
</div> <el-table-column
</el-form-item> label="受理时间"
</el-col> prop="discoveryTime"
<el-col :span="6"> show-overflow-tooltip
<el-form-item label=" 受理时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="具体内容">
<el-input
placeholder="请输入"
v-model="query.thingDesc"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分发状态" >
<el-select v-model="query.distributionState" clearable>
<el-option
v-for="item in dict.distributionState"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/> />
</el-select> <el-table-column
</el-form-item> label="问题发生时间"
</el-col> prop="happenTime"
show-overflow-tooltip
<el-col :span="6">
<el-form-item label="是否属实">
<el-select
clearable
v-model="query.checkStatus"
>
<el-option
v-for="item in dict.inspectCase"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/> />
</el-select> <el-table-column
</el-form-item> label="问题来源"
</el-col> prop="problemSources"
show-overflow-tooltip
</el-row> />
</el-form> <el-table-column
<div class="mb-25 flex between"> label="投诉人"
<div> prop="responderName"
<el-button type="primary" @click="show = true" width="90"
>数据导入 />
</el-button <el-table-column
> label="投诉人电话"
<el-badge prop="responderPhone"
:value="distributeList.length" width="120"
class="ml-10" />
v-if="distributeList.length" <el-table-column label="业务类别" prop="businessTypeName" />
> <el-table-column label="涉嫌问题" prop="involveProblem" />
<el-button <!-- <el-table-column label="涉及警种" prop="policeTypeName"/>-->
type="primary" <el-table-column label="涉及单位" prop="thirdDepartName" />
@click="distributeListShow = true" <el-table-column
>问题下发 label="具体内容"
</el-button prop="thingDesc"
> show-overflow-tooltip
</el-badge> />
</div> <el-table-column label="是否属实" prop="isReal">
<div> <template v-slot="scope">
<el-button type="primary" @click="getList"> <span v-if="scope.row.isReal === 1">属实</span>
<template #icon> <span v-else-if="scope.row.isReal === 2">部分属实</span>
<icon name="el-icon-Search"/> <span v-else-if="scope.row.isReal === 3">不属实</span>
</template> <span v-else>未知状态</span>
查询 </template>
</el-button </el-table-column>
> <el-table-column label="状态">
<el-button @click="reset">重置</el-button> <template #default="{ row }">
</div> <el-tag
</div> >{{
</header> getDictLable(
<div class="table-container"> dict.distributionState,
<el-table :data="list"> row.distributionState
<el-table-column )
label="案件编号" }}
prop="originId" </el-tag>
show-overflow-tooltip </template>
/> </el-table-column>
<el-table-column <el-table-column label="操作" width="200">
label="受理时间" <template #default="{ row }">
prop="discoveryTime" <el-button type="primary" link @click="handleDetail(row)" v-if="row.distributionState === '1'"
show-overflow-tooltip >问题详情
/> </el-button>
<el-table-column <template
label="问题发生时间" v-if="
prop="happenTime"
show-overflow-tooltip
/>
<el-table-column
label="问题来源"
prop="problemSources"
show-overflow-tooltip
/>
<el-table-column
label="投诉人"
prop="responderName"
width="90"
/>
<el-table-column
label="投诉人电话"
prop="responderPhone"
width="120"
/>
<el-table-column label="业务类别" prop="businessTypeName"/>
<el-table-column label="涉嫌问题" prop="involveProblem"/>
<!-- <el-table-column label="涉及警种" prop="policeTypeName"/>-->
<el-table-column label="涉及单位" prop="thirdDepartName"/>
<el-table-column
label="具体内容"
prop="thingDesc"
show-overflow-tooltip
/>
<el-table-column label="是否属实" prop="isReal">
<template v-slot="scope">
<span v-if="scope.row.isReal === 1">属实</span>
<span v-else-if="scope.row.isReal === 2">部分属实</span>
<span v-else-if="scope.row.isReal === 3">不属实</span>
<span v-else>未知状态</span>
</template>
</el-table-column>
<el-table-column label="状态">
<template #default="{ row }">
<el-tag>{{
getDictLable(
dict.distributionState,
row.distributionState
)
}}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<template
v-if="
row.distributionState === row.distributionState ===
DistributionState.UNDISTRIBUTED DistributionState.UNDISTRIBUTED
" "
> >
<el-button <el-button
type="primary" type="primary"
link link
@click="handleAddDistribute(row)" @click="handleAddDistribute(row)"
v-if=" v-if="
distributeList.filter( distributeList.filter(
(item) => item.originId === row.originId (item) => item.originId === row.originId
).length === 0 ).length === 0
" "
>加入问题下发 >加入问题下发
</el-button </el-button>
> <el-button
<el-button type="info"
type="info" link
link v-else
v-else @click="handleRemoveDistribute(row)"
@click="handleRemoveDistribute(row)" >移除
>移除 </el-button>
</el-button </template>
>
</template>
<el-button type="danger" link @click="handleDel(row)" <el-button type="danger" link @click="handleDel(row)"
>删除 >删除
</el-button </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"
> >
</template> </el-pagination>
</el-table-column> </div>
</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>
</div>
<data-import-case <data-import-case
v-model="show" v-model="show"
title="案件核查 数据导入" title="案件核查 数据导入"
@close="show = false" @close="show = false"
@update="getList" @update="getList"
/> />
<el-dialog <el-dialog
title="问题分发" title="问题分发"
v-model="distributeListShow" v-model="distributeListShow"
width="80vw" width="80vw"
top="5vh" top="5vh"
> >
<header> <header>
<div class="flex v-center end mb-20"> <div class="flex v-center end mb-20">
<span class="mr-20" <span class="mr-20"
> >
<span class="text-primary">{{ <span class="text-primary">{{
distributeList.length distributeList.length
}}</span> }}</span>
条数据</span 条数据</span
> >
</div> </div>
</header> </header>
<div style="min-height: 500px"> <div style="min-height: 500px">
<div class="table-container"> <div class="table-container">
<el-table :data="distributeList"> <el-table :data="distributeList">
<el-table-column <el-table-column
label="案件编号" label="案件编号"
prop="originId" prop="originId"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column <el-table-column
label="受理时间" label="受理时间"
prop="discoveryTime" prop="discoveryTime"
show-overflow-tooltip show-overflow-tooltip
/> />
<!-- <el-table-column label="问题发生时间" prop="happenTime" show-overflow-tooltip />--> <el-table-column
<el-table-column label="问题来源"
label="问题来源" prop="problemSources"
prop="problemSources" show-overflow-tooltip
show-overflow-tooltip />
/> <el-table-column
<el-table-column label="投诉人"
label="投诉人" prop="responderName"
prop="responderName" width="90"
width="90" />
/> <el-table-column
<el-table-column label="投诉人电话"
label="投诉人电话" prop="contactPhone"
prop="contactPhone" width="120"
width="120" />
/> <el-table-column label="业务类别" prop="businessTypeName" />
<el-table-column label="业务类别" prop="businessTypeName"/> <el-table-column label="涉嫌问题" prop="involveProblem" />
<el-table-column label="涉嫌问题" prop="involveProblem"/> <el-table-column
<!-- <el-table-column label="涉及警种" prop="policeTypeName" />--> label="涉及单位"
<el-table-column prop="involveDepartName"
label="涉及单位" />
prop="involveDepartName" <el-table-column
/> label="具体内容"
<el-table-column prop="thingDesc"
label="具体内容" show-overflow-tooltip
prop="thingDesc" />
show-overflow-tooltip <el-table-column label="操作" width="140">
/> <template #default="{ row }">
<el-table-column label="操作" width="140"> <el-button
<template #default="{ row }"> type="info"
link
<el-button @click="handleRemoveDistribute(row)"
type="info" >移除
link </el-button>
@click="handleRemoveDistribute(row)" </template>
>移除 </el-table-column>
</el-button </el-table>
> </div>
</template> </div>
</el-table-column> <footer class="flex end mt-20">
</el-table> <el-button
</div> type="primary"
</div> size="large"
<footer class="flex end mt-20"> @click="handleShowDistributeDialog"
<el-button :disabled="distributeList.length === 0"
type="primary" >确认数据
size="large" </el-button>
@click="handleShowDistributeDialog" </footer>
:disabled="distributeList.length === 0" </el-dialog>
>确认数据
</el-button
>
</footer>
</el-dialog>
<el-dialog title="任务分发" v-model="distributeShow" width="50vw" top="5vh"> <el-dialog title="任务分发" v-model="distributeShow" width="50vw" top="5vh">
<el-form :label-width="120" ref="formRef" :model="form"> <el-form :label-width="120" ref="formRef" :model="form">
<el-form-item <el-form-item
label="办理时限" label="办理时限"
prop="timeLimit" prop="timeLimit"
:rules="{ :rules="{
required: true, required: true,
message: '请选择办理时限', message: '请选择办理时限',
}" }"
> >
<time-limit-select <time-limit-select
v-model="form.timeLimit" v-model="form.timeLimit"
v-model:maxSignDuration="form.maxSignDuration" v-model:maxSignDuration="form.maxSignDuration"
v-model:maxHandleDuration="form.maxHandleDuration" v-model:maxHandleDuration="form.maxHandleDuration"
v-model:maxExtensionDuration="form.maxExtensionDuration" v-model:maxExtensionDuration="form.maxExtensionDuration"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="审核流程" label="审核流程"
prop="approvalFlow" prop="approvalFlow"
:rules="{ :rules="{
required: true, required: true,
message: '请选择审核流程', message: '请选择审核流程',
}" }"
> >
<el-radio-group v-model="form.approvalFlow"> <el-radio-group v-model="form.approvalFlow">
<el-radio <el-radio
v-for="item in dict.approvalFlow" v-for="item in dict.approvalFlow"
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ >{{ item.dictLabel
item.dictLabel }}{{ item.remark ? `(${item.remark})` : "" }}
}}{{ item.remark ? `(${item.remark})` : "" }} </el-radio>
</el-radio </el-radio-group>
> <div class="tips mt-10">
</el-radio-group> <p>
<div class="tips mt-10"> 三级审核 在问题提交办结时需经过所队>二级机构>市局三级审核通过后方可办结
<p> </p>
三级审核 在问题提交办结时需经过所队>二级机构>市局三级审核通过后方可办结 <p>
</p> 二级审核 在问题提交办结时仅需经过所队>二级机构两级审核通过后即可办结
<p> </p>
二级审核 在问题提交办结时仅需经过所队>二级机构两级审核通过后即可办结 </div>
</p> </el-form-item>
</div> </el-form>
</el-form-item> <footer class="flex end mt-20">
</el-form> <el-button type="primary" size="large" @click="handleSubmit"
<footer class="flex end mt-20"> >确认下发
<el-button </el-button>
type="primary" </footer>
size="large" </el-dialog>
@click="handleSubmit"
>确认下发 <negative-dialog
</el-button v-model="negativeShow"
> :id="activeNegativeId"
</footer> @close="negativeShow = false"
</el-dialog> />
</template> </template>
<script setup> <script setup>
import {BASE_PATH} from "@/api/request"; import { BASE_PATH } from "@/api/request";
import { import {
listCaseVerif, listCaseVerif,
delCaseVerif, delCaseVerif,
distributeCaseVerif, distributeCaseVerif,
getNegativeId
} from "@/api/data/caseVerif"; } from "@/api/data/caseVerif";
import {DistributionState} from "@/enums/dictEnums"; import { DistributionState } from "@/enums/dictEnums";
import {getDictLable} from "@/utils/util"; import { getDictLable } from "@/utils/util";
import feedback from "@/utils/feedback"; import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts([ const dict = catchStore.getDicts([
"distributionState", "distributionState",
"timeLimit", "timeLimit",
"approvalFlow", "approvalFlow",
"inspectCase", "inspectCase",
]); ]);
const query = ref({ const query = ref({
size: 10, size: 10,
current: 1, current: 1,
responderKey: "name", responderKey: "name",
}); });
const list = ref([]); const list = ref([]);
const total = ref(0); const total = ref(0);
function getList() { function getList() {
listCaseVerif(query.value).then((data) => { listCaseVerif(query.value).then((data) => {
list.value = data.records; list.value = data.records;
total.value = data.total; total.value = data.total;
}); });
} }
function reset() { function reset() {
query.value = { query.value = {
size: 10, size: 10,
current: 1, current: 1,
responderKey: "name", responderKey: "name",
}; };
getList(); getList();
} }
getList(); getList();
@ -420,9 +412,9 @@ getList();
const show = ref(false); const show = ref(false);
async function handleDel(row) { async function handleDel(row) {
await feedback.confirm("确定要删除该数据?"); await feedback.confirm("确定要删除该数据?");
await delCaseVerif(row.originId); await delCaseVerif(row.originId);
getList(); getList();
} }
const distributeListShow = ref(false); const distributeListShow = ref(false);
@ -430,34 +422,41 @@ const distributeList = ref([]);
const distributeShow = ref(false); const distributeShow = ref(false);
function handleAddDistribute(row) { function handleAddDistribute(row) {
distributeList.value.push(row); distributeList.value.push(row);
} }
function handleShowDistributeDialog() { function handleShowDistributeDialog() {
distributeShow.value = true; distributeShow.value = true;
} }
const form = ref({}); const form = ref({});
const formRef = ref() const formRef = ref();
function handleRemoveDistribute(row) { function handleRemoveDistribute(row) {
distributeList.value.splice( distributeList.value.splice(
distributeList.value.findIndex( distributeList.value.findIndex(
(item) => item.originId === row.originId (item) => item.originId === row.originId
), ),
1 1
); );
} }
async function handleSubmit() { async function handleSubmit() {
await formRef.value.validate() await formRef.value.validate();
form.value.data = distributeList.value form.value.data = distributeList.value;
await distributeCaseVerif(form.value) await distributeCaseVerif(form.value);
form.value = {} form.value = {};
distributeShow.value = false distributeShow.value = false;
distributeListShow.value = false distributeListShow.value = false;
feedback.msgSuccess('下发成功') feedback.msgSuccess("下发成功");
getList() getList();
}
const negativeShow = ref(false)
const activeNegativeId = ref('')
async function handleDetail(row) {
activeNegativeId.value = await getNegativeId(row.originId)
negativeShow.value = true
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

49
src/views/data/Gabxf.vue

@ -3,6 +3,21 @@
<header> <header>
<el-form :label-width="114"> <el-form :label-width="114">
<el-row> <el-row>
<el-col :span="6">
<el-form-item label="登记时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="录入时间">
<date-time-range-picker-ext
v-model="query.createTime"
/>
</el-form-item>
</el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="信件编号"> <el-form-item label="信件编号">
<el-input <el-input
@ -30,13 +45,6 @@
</div> </div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6">
<el-form-item label="登记时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="具体内容"> <el-form-item label="具体内容">
<el-input <el-input
@ -45,6 +53,28 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<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-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"> <el-col :span="6">
<el-form-item label="状态"> <el-form-item label="状态">
<el-select <el-select
@ -239,10 +269,7 @@ import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts([ const dict = catchStore.getDicts([
"distributionState", "distributionState",
"timeLimit", "initialPetition"
"approvalFlow",
"distributionFlow",
"distributionState",
]); ]);
const query = ref({ const query = ref({

46
src/views/data/Gjxf.vue

@ -3,6 +3,21 @@
<header> <header>
<el-form :label-width="114"> <el-form :label-width="114">
<el-row> <el-row>
<el-col :span="6">
<el-form-item label="登记时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="录入时间">
<date-time-range-picker-ext
v-model="query.createTime"
/>
</el-form-item>
</el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="信件编号"> <el-form-item label="信件编号">
<el-input <el-input
@ -30,13 +45,6 @@
</div> </div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6">
<el-form-item label="登记时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="具体内容"> <el-form-item label="具体内容">
<el-input <el-input
@ -45,6 +53,28 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<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-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"> <el-col :span="6">
<el-form-item label="状态"> <el-form-item label="状态">
<el-select <el-select
@ -234,7 +264,7 @@ import { getDictLable } from "@/utils/util";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts(["distributionState"]); const dict = catchStore.getDicts(["distributionState", "initialPetition"]);
const query = ref({ const query = ref({
size: 10, size: 10,

129
src/views/data/ImportRecords.vue

@ -0,0 +1,129 @@
<template>
<div class="container">
<header>
<el-form :label-width="120">
<el-row>
<el-col :span="6">
<el-form-item label="数据来源">
<el-select v-model="query.source" clearable>
<el-option value="公安部信访">公安部信访</el-option>
<el-option value="国家信访">国家信访</el-option>
<el-option value="案件核查">案件核查</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="创建时间">
<date-time-range-picker-ext v-model="query.crtTime"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex end mb-20">
<el-button type="primary" @click="getList">
<template #icon>
<icon name="el-icon-Search" />
</template>
查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</header>
<div class="table-container" v-loading="loading">
<el-table :data="list">
<el-table-column label="数据来源" prop="source" show-overflow-tooltip />
<el-table-column
label="导入数量"
prop="importRow"
align="center"
/>
<el-table-column label="操作时间" prop="crtTime" />
<el-table-column label="操作人" prop="crtUser" />
<el-table-column label="状态" prop="status">
<template #default="{ row }">
<el-tag type="success" v-if="row.status === '0'"
>导入成功</el-tag
>
<el-tag type="danger" v-else-if="row.status === '1'"
>导入失败</el-tag
>
</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>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
import { listNegativeTask } from "@/api/work/negativeTask";
const list = ref([]);
const query = ref({
size: 10,
current: 1,
category: '1'
});
const total = ref(0);
const loading = ref(true)
function getList() {
loading.value = true
listNegativeTask(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
loading.value = false
});
}
function reset() {
query.value = {
size: 10,
current: 1,
category: '1'
};
getList();
}
onMounted(() => {
getList();
});
function handleDownload(row) {
if (row.status !== '1') {
}
fetch(`${BASE_PATH}/file/stream${row.filePath}`)
.then((response) => {
console.log(response);
return response.blob();
})
.then((res) => {
console.log(res);
const blob = new Blob([res], {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
});
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", row.taskName + ".xlsx");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
});
}
</script>
<style lang="scss" scoped>
</style>

6
src/views/data/Mail12337.vue

@ -203,6 +203,7 @@
</div> </div>
</template> </template>
</el-upload> </el-upload>
<div class="mt-10">说明请上传12337信访投诉台账表格进行导入操作上传成功后点击下一步进行数据核验</div>
</div> </div>
</template> </template>
<template v-if="activeStep === 1"> <template v-if="activeStep === 1">
@ -383,6 +384,7 @@
/> />
</el-table> </el-table>
</div> </div>
<div class="mt-10">说明数据校验展示信访投诉关键信息标红内容为必填项</div>
<div class="text-danger text-wrap mt-10 text-small"> <div class="text-danger text-wrap mt-10 text-small">
{{ errMsg }} {{ errMsg }}
</div> </div>
@ -577,7 +579,7 @@ const router = useRouter();
const query = ref({ const query = ref({
size: 10, size: 10,
current: 1, current: 1,
problemSourcesCode: ProblemSources.XF12337, responderValue: 'name'
}); });
const list = ref([]); const list = ref([]);
@ -594,7 +596,7 @@ function reset() {
query.value = { query.value = {
size: 10, size: 10,
current: 1, current: 1,
problemSourcesCode: ProblemSources.XF12337, responderValue: 'name'
}; };
getList(); getList();
} }

196
src/views/data/Mailbox.vue

@ -0,0 +1,196 @@
<template>
<div class="container">
<header>
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="信件编号">
<el-input
placeholder="请输入"
v-model="query.originId"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="投诉人">
<div class="flex gap">
<el-select
v-model="query.responderKey"
style="width: 160px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="请输入"
v-model="query.responderValue"
clearable
/>
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="来信时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="具体内容">
<el-input
placeholder="请输入"
v-model="query.thingDesc"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="mb-25 flex end">
<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="originId"
show-overflow-tooltip
/>
<el-table-column
label="来信时间"
prop="discoveryTime"
show-overflow-tooltip
/>
<el-table-column
label="投诉人"
prop="responderName"
width="90"
/>
<el-table-column label="电话" prop="contactPhone" />
<el-table-column
label="具体内容"
prop="thingDesc"
show-overflow-tooltip
/>
<el-table-column label="办理单位" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.handleSecondDepartName }}</span>
<span>{{ row.handleThreeDepartName }}</span>
</template>
</el-table-column>
<el-table-column
label="是否属实"
prop="checkStatusName"
width="100"
align="center"
/>
<el-table-column label="办理状态" width="110">
<template #default="{ row }">
<el-tag
:type="
row.processingStatus ===
ProcessingStatus.COMPLETED
? 'success'
: 'primary'
"
v-if="row.processingStatus"
>{{
getDictLable(
dict.processingStatus,
row.processingStatus
)
}}</el-tag
>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleAction(row)"
>详情</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>
<negative-dialog
v-model="show"
:id="activeNegativeId"
@close="show = false"
/>
</template>
<script setup>
import { ProcessingStatus } from "@/enums/flowEnums";
import {
listMailbox
} from "@/api/data/mailbox";
import feedback from "@/utils/feedback";
import { getDictLable } from "@/utils/util";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts(["distributionState"]);
const query = ref({
size: 10,
current: 1,
responderKey: "name",
});
const list = ref([]);
const total = ref(0);
function getList() {
listMailbox(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
size: 10,
current: 1,
responderKey: "name",
};
getList();
}
getList();
const show = ref(false);
const activeNegativeId = ref("");
function handleAction(row) {
show.value = true;
activeNegativeId.value = row.id;
}
</script>
<style lang="scss" scoped>
</style>

628
src/views/data/VideoInspection.vue

@ -1,122 +1,354 @@
<template> <template>
<div class="container"> <div class="container">
<header> <el-tabs>
<el-form :label-width="114"> <el-tab-pane label="未下发">
<el-row> <header>
<el-col :span="6"> <el-form :label-width="114">
<el-form-item label="预警类型"> <el-row>
<el-input <el-col :span="6">
placeholder="请输入" <el-form-item label="预警类型">
v-model="query.systemKeyName" <el-input
clearable placeholder="请输入"
/> v-model="query.systemKeyName"
</el-form-item> clearable
</el-col> />
<el-col :span="6"> </el-form-item>
<el-form-item label="案事件名称"> </el-col>
<el-input <el-col :span="6">
placeholder="请输入" <el-form-item label="案事件名称">
v-model="query.title" <el-input
clearable placeholder="请输入"
/> v-model="query.title"
</el-form-item> clearable
</el-col> />
<el-col :span="6"> </el-form-item>
<el-form-item label="发生单位"> </el-col>
<depart-tree-select <el-col :span="6">
v-model="query.departId" <el-form-item label="发生单位">
placeholder="涉及单位" <depart-tree-select
/> v-model="query.departId"
</el-form-item> placeholder="涉及单位"
</el-col> />
</el-row> </el-form-item>
</el-form> </el-col>
<div class="flex between mt-20 mb-26"> </el-row>
<div class="flex gap"> </el-form>
<el-button type="primary" @click="handleBathJoin"> <div class="flex between mt-20 mb-26">
<template #icon> <div class="flex gap">
<icon name="el-icon-Plus" /> <el-button type="primary" @click="handleBathJoin">
</template> <template #icon>
批量加入</el-button <icon name="el-icon-Plus" />
> </template>
<el-badge :value="distributeList.length"> 批量加入</el-button
<el-button >
type="primary" <el-badge :value="distributeList.length">
:disabled="distributeList.length === 0" <el-button
@click="manualShow = true" type="primary"
>分发列表</el-button :disabled="distributeList.length === 0"
@click="manualShow = true"
>分发列表</el-button
>
</el-badge>
</div>
<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" ref="tableRef">
<el-table-column
type="selection"
width="55"
:selectable="selectable"
/>
<el-table-column
label="预警级别"
prop="alarmLevel"
width="100"
align="center"
> >
</el-badge> <template #default="{ row }">
<span v-if="row.alarmLevel"
>{{ row.alarmLevel }}</span
>
</template>
</el-table-column>
<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="下发状态" width="120">
<template #default="{ row }">
<span
class="text-danger"
v-if="row.distributionState === '0'"
>未下发</span
>
<span
class="text-success"
v-if="row.distributionState === '1'"
>已下发</span
>
</template>
</el-table-column>
<el-table-column label="操作" width="160">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleShowInfo(row, false)"
>查看详情</el-button
>
<el-button
link
@click="handleRemoveManuel(row)"
v-if="distributeList.includes(row)"
>移除</el-button
>
</template>
</el-table-column>
</el-table>
</div> </div>
<div> <div class="flex end mt-8">
<el-button type="primary" @click="getList"> <el-pagination
<template #icon @size-change="getList"
><icon name="el-icon-Search" @current-change="getList"
/></template> :page-sizes="[10, 20, 50]"
查询</el-button v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
> >
<el-button @click="reset">重置</el-button> </el-pagination>
</div> </div>
</div> </el-tab-pane>
</header> <el-tab-pane label="已下发">
<div class="table-container"> <header>
<el-table :data="list" ref="tableRef"> <el-form :label-width="114">
<el-table-column <el-row>
type="selection" <el-col :span="6">
width="55" <el-form-item label="预警类型">
:selectable="selectable" <el-input
/> placeholder="请输入"
<el-table-column v-model="query2.systemKeyName"
label="预警级别" clearable
prop="alarmLevel" />
width="100" </el-form-item>
align="center" </el-col>
> <el-col :span="6">
<template #default="{ row }"> <el-form-item label="案事件名称">
<span v-if="row.alarmLevel" <el-input
>{{ row.alarmLevel }}</span placeholder="请输入"
> v-model="query2.title"
</template> clearable
</el-table-column> />
<el-table-column label="预警类别" prop="systemKeyName" /> </el-form-item>
<el-table-column label="预警时间" prop="rqsj" /> </el-col>
<el-table-column label="案事件名称" prop="title" /> <el-col :span="6">
<el-table-column label="发生单位名称" prop="fsdwGajgmc" /> <el-form-item label="发生单位">
<el-table-column label="下发状态" width="120"> <depart-tree-select
<template #default="{ row }"> v-model="query2.departId"
<span class="text-danger">未下发</span> placeholder="涉及单位"
</template> />
</el-table-column> </el-form-item>
<el-table-column label="操作" width="160"> </el-col>
<template #default="{ row }"> </el-row>
<el-button </el-form>
type="primary" <div class="flex end mt-20 mb-26">
link <div>
@click="handleShowInfo(row)" <el-button type="primary" @click="getList2">
>查看详情</el-button <template #icon
><icon name="el-icon-Search"
/></template>
查询</el-button
>
<el-button @click="reset1">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list2">
<el-table-column
label="预警级别"
prop="alarmLevel"
width="100"
align="center"
> >
<el-button <template #default="{ row }">
link <span v-if="row.alarmLevel"
@click="handleRemoveManuel(row)" >{{ row.alarmLevel }}</span
v-if="distributeList.includes(row)" >
>移除</el-button </template>
</el-table-column>
<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="操作时间"
width="120"
prop="updateTime"
/>
<el-table-column label="下发状态" width="120">
<template #default="{ row }">
<span
class="text-danger"
v-if="row.distributionState === '0'"
>未下发</span
>
<span
class="text-success"
v-if="row.distributionState === '1'"
>已下发</span
>
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleShowInfo(row, true)"
>查看详情</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList2"
@current-change="getList2"
:page-sizes="[10, 20, 50]"
v-model:page-size="query2.size"
v-model:current-page="query2.current"
layout="total, sizes, prev, pager, next"
:total="total2"
>
</el-pagination>
</div>
</el-tab-pane>
<el-tab-pane label="无效">
<header>
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="预警类型">
<el-input
placeholder="请输入"
v-model="query1.systemKeyName"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="案事件名称">
<el-input
placeholder="请输入"
v-model="query1.title"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="发生单位">
<depart-tree-select
v-model="query1.departId"
placeholder="涉及单位"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex end mt-20 mb-26">
<div>
<el-button type="primary" @click="getList1">
<template #icon
><icon name="el-icon-Search"
/></template>
查询</el-button
>
<el-button @click="reset1">重置</el-button>
</div>
</div>
</header>
<div class="table-container">
<el-table :data="list1">
<el-table-column
label="预警级别"
prop="alarmLevel"
width="100"
align="center"
> >
</template> <template #default="{ row }">
</el-table-column> <span v-if="row.alarmLevel"
</el-table> >{{ row.alarmLevel }}</span
</div> >
<div class="flex end mt-8"> </template>
<el-pagination </el-table-column>
@size-change="getList" <el-table-column
@current-change="getList" label="预警类别"
:page-sizes="[10, 20, 50]" prop="systemKeyName"
v-model:page-size="query.size" />
v-model:current-page="query.current" <el-table-column label="预警时间" prop="rqsj" />
layout="total, sizes, prev, pager, next" <el-table-column label="案事件名称" prop="title" />
:total="total" <el-table-column
> label="发生单位名称"
</el-pagination> prop="fsdwGajgmc"
</div> />
<el-table-column
label="操作时间"
width="120"
prop="updateTime"
/>
<el-table-column label="操作" width="180">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleShowInfo(row, true)"
>查看详情</el-button
>
<el-button link @click="handleRestore(row)"
>恢复数据</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex end mt-8">
<el-pagination
@size-change="getList1"
@current-change="getList1"
:page-sizes="[10, 20, 50]"
v-model:page-size="query1.size"
v-model:current-page="query1.current"
layout="total, sizes, prev, pager, next"
:total="total1"
>
</el-pagination>
</div>
</el-tab-pane>
</el-tabs>
</div> </div>
<el-dialog <el-dialog
@ -140,19 +372,19 @@
>{{ info.alarmLevel }}</span >{{ info.alarmLevel }}</span
> >
</div> </div>
<div class="col col-12"> <div class="col col-6">
<label>登记单位</label> <label>登记单位</label>
<span>{{ info.registrationDepartName }}</span> <span>{{ info.registrationDepartName }}</span>
</div> </div>
<div class="col col-12"> <div class="col col-6">
<label>发生单位</label> <label>发生单位</label>
<span>{{ info.happenDepartName }}</span> <span>{{ info.happenDepartName }}</span>
</div> </div>
<div class="col col-24"> <div class="col col-12">
<label>督察方式</label> <label>督察方式</label>
<span>{{ info.systemKeyName }}</span> <span>{{ info.systemKeyName }}</span>
</div> </div>
<div class="col col-24"> <div class="col col-12">
<label>预警标题</label> <label>预警标题</label>
<span>{{ info.title }}</span> <span>{{ info.title }}</span>
</div> </div>
@ -184,46 +416,54 @@
</el-scrollbar> </el-scrollbar>
</el-col> </el-col>
<el-col :span="19"> <el-col :span="19">
<el-scrollbar height="560px"> <div style="height: calc(96vh - 260px)">
<div class="row"> <div class="row">
<div class="col col-24"> <div class="col col-12">
<label>发生单位</label> <label>发生单位</label>
<span>{{ info.happenDepartName }}</span> <span>{{ info.happenDepartName }}</span>
</div> </div>
<div class="col col-24"> <div class="col col-12">
<label>预警时间</label> <label>预警时间</label>
<span>{{ activeZl.dmtbzrqsj }}</span> <span>{{ activeZl.dmtbzrqsj }}</span>
</div> </div>
</div> </div>
<div> <div
<img style="height: calc(100% - 32px)"
style="width: 100%" class="flex center"
:src="activeZl.dzwjwz" >
alt="" <img :src="activeZl.dzwjwz" alt="" />
/>
</div> </div>
</el-scrollbar> </div>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
<footer class="flex end mt-20"> <footer class="flex end mt-20" style="min-height: 40px">
<el-button <template v-if="!disabledFlag">
size="large" <el-button
@click="handleJoin" size="large"
v-if="!distributeList.includes(activeRow)" type="danger"
><template #icon> <icon name="el-icon-Plus" /> </template @click="handleUpdateState"
>加入分发列表</el-button v-if="!distributeList.includes(activeRow)"
> >查否</el-button
<el-button >
size="large" <el-button
@click="handleRemoveManuel(activeRow)" size="large"
v-else @click="handleJoin"
><template #icon> <icon name="el-icon-Minus" /> </template v-if="!distributeList.includes(activeRow)"
>从分发列表移除</el-button ><template #icon> <icon name="el-icon-Plus" /> </template
> >加入分发列表</el-button
<el-button size="large" type="primary" @click="handleNext" >
>下一条</el-button <el-button
> size="large"
@click="handleRemoveManuel(activeRow)"
v-else
><template #icon> <icon name="el-icon-Minus" /> </template
>从分发列表移除</el-button
>
<el-button size="large" type="primary" @click="handleNext"
>下一条</el-button
>
</template>
</footer> </footer>
</el-dialog> </el-dialog>
@ -467,6 +707,7 @@ import {
listVideoInspection, listVideoInspection,
getVideoInspectionInfo, getVideoInspectionInfo,
distributeData, distributeData,
updateState,
} from "@/api/data/videoInspection"; } from "@/api/data/videoInspection";
import feedback from "@/utils/feedback"; import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
@ -485,28 +726,82 @@ const dict = catchStore.getDicts([
const query = ref({ const query = ref({
current: 1, current: 1,
size: 10, size: 10,
state: "1",
distributionState: "0",
}); });
const list = ref([]); const list = ref([]);
const total = ref(0); const total = ref(0);
function getList() { let pages = 1;
listVideoInspection(query.value).then((data) => { async function getList() {
list.value = data.records; const data = await listVideoInspection(query.value);
total.value = data.total; list.value = data.records;
}); total.value = data.total;
pages = data.pages;
} }
onMounted(() => { onMounted(() => {
getList(); getList();
getList1();
getList2();
}); });
function reset() { function reset() {
query.value = { query.value = {
current: 1, current: 1,
size: 10, size: 10,
state: "1",
distributionState: '0'
}; };
getList(); getList();
} }
//------------------------------
const query1 = ref({
current: 1,
size: 10,
state: "0",
});
const list1 = ref([]);
const total1 = ref(0);
async function getList1() {
const data = await listVideoInspection(query1.value);
list1.value = data.records;
total1.value = data.total;
}
function reset1() {
query1.value = {
current: 1,
size: 10,
state: "0",
};
getList1();
}
//------------------------------
const query2 = ref({
current: 1,
size: 10,
state: "1",
distributionState: '1'
});
const list2 = ref([]);
const total2 = ref(0);
async function getList2() {
const data = await listVideoInspection(query2.value);
list2.value = data.records;
total2.value = data.total;
}
function reset2() {
query2.value = {
current: 1,
size: 10,
state: "1",
distributionState: "1",
};
getList2();
}
const show = ref(false); const show = ref(false);
const infoLoading = ref(false); const infoLoading = ref(false);
@ -514,10 +809,11 @@ const info = ref({});
const activeZl = ref({}); const activeZl = ref({});
const activeRow = ref({}); const activeRow = ref({});
async function handleShowInfo(row) { const disabledFlag = ref(false);
async function handleShowInfo(row, disabled) {
activeRow.value = row; activeRow.value = row;
show.value = true; show.value = true;
disabledFlag.value = disabled;
} }
const manualShow = ref(false); const manualShow = ref(false);
@ -567,14 +863,27 @@ async function handleSubmit() {
submitLoading.value = false; submitLoading.value = false;
throw e; throw e;
} }
distributeShow.value = false;
manualShow.value = false;
submitLoading.value = false; submitLoading.value = false;
getList(); getList();
getList2();
distributeList.value = []; distributeList.value = [];
await feedback.confirm("问题已下发,请到“综合查询”页面查看");
router.push("/query");
} }
function handleNext() { async function handleNext() {
let index = list.value.indexOf(activeRow.value); let index = list.value.indexOf(activeRow.value);
if (index === list.value.length - 1) { if (index === list.value.length - 1) {
if (query.value.current === pages) {
infoLoading.value = false;
feedback.alert("当前已是最后一条数据!", "温馨提示");
return;
}
query.value.current += 1;
infoLoading.value = true;
await getList();
index = 0; index = 0;
} else { } else {
index++; index++;
@ -592,6 +901,23 @@ watch(activeRow, async () => {
} }
infoLoading.value = false; infoLoading.value = false;
}); });
async function handleUpdateState() {
await feedback.confirm("确认要将该数据判断为无效?");
infoLoading.value = true;
await updateState(activeRow.value.id, "0");
getList();
getList1();
handleNext();
}
async function handleRestore(row) {
await feedback.confirm("确认要恢复该数据?");
infoLoading.value = true;
await updateState(row.id, "1");
getList();
getList1();
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.top-container { .top-container {

1262
src/views/datav/AuditSuper.vue

File diff suppressed because it is too large Load Diff

48
src/views/datav/CaseVerif.vue

@ -485,17 +485,7 @@ const jbcloption = ref({
label: { label: {
color: "#fff", color: "#fff",
}, },
data: [ data: [],
// {value: 14, name: ""},
// {value: 11, name: ""},
// {value: 3, name: ""},
// {value: 2, name: ""},
// {value: 12, name: ""},
// {value: 8, name: ""},
// {value: 2, name: ""},
// {value: 2, name: ""},
// {value: 3, name: ""},
],
}, },
], ],
}); });
@ -510,17 +500,7 @@ const tzcloption = ref({
label: { label: {
color: "#fff", color: "#fff",
}, },
data: [ data: [],
// {value: 14, name: ""},
// {value: 11, name: ""},
// {value: 3, name: ""},
// {value: 2, name: ""},
// {value: 12, name: ""},
// {value: 8, name: ""},
// {value: 2, name: ""},
// {value: 2, name: ""},
// {value: 3, name: ""},
],
}, },
], ],
}); });
@ -695,23 +675,23 @@ const setupEventListeners = () => {
}; };
const caseVerifRankAnimationStop = () => { const caseVerifRankAnimationStop = () => {
const temp = caseVerifRankTabs.value.$el; const temp = caseVerifRankTabs.value.$el;
temp.addEventListener('mouseenter', () => { temp?.addEventListener('mouseenter', () => {
clearInterval(caseVerifRankIntervalId) clearInterval(caseVerifRankIntervalId)
}); });
temp.addEventListener('mouseleave', () => { temp?.addEventListener('mouseleave', () => {
clearInterval(caseVerifRankIntervalId); // clearInterval(caseVerifRankIntervalId); //
caseVerifRankIntervalId = setInterval(caseVerifRankAnimation, 3000); caseVerifRankIntervalId = setInterval(caseVerifRankAnimation, 3000);
}); });
} }
const caseVerifProPropertyAnimationStop = () => { const caseVerifProPropertyAnimationStop = () => {
const temp = zfbaProProperty?.value?.chart; const temp = zfbaProProperty?.value?.chart;
temp.on('mousemove', (e) => { temp?.on('mousemove', (e) => {
clearInterval(caseVerifProPropertyIntervalId); clearInterval(caseVerifProPropertyIntervalId);
temp.dispatchAction({type: "downplay", seriesIndex: 0,}); temp.dispatchAction({type: "downplay", seriesIndex: 0,});
temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,}); temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,});
temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,}); temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,});
}) })
temp.on('mouseout', () => { temp?.on('mouseout', () => {
clearInterval(caseVerifProPropertyIntervalId); clearInterval(caseVerifProPropertyIntervalId);
caseVerifProPropertyIntervalId = setInterval(caseVerifProPropertyAnimation, 2000); caseVerifProPropertyIntervalId = setInterval(caseVerifProPropertyAnimation, 2000);
}) })
@ -719,50 +699,50 @@ const caseVerifProPropertyAnimationStop = () => {
const caseVerifMapAnimationStop = () => { const caseVerifMapAnimationStop = () => {
const mapTemp = caseVerifMap?.value?.chart; const mapTemp = caseVerifMap?.value?.chart;
// //
mapTemp.on('mousemove', (e) => { mapTemp?.on('mousemove', (e) => {
clearInterval(caseVerifMapIntervalId); clearInterval(caseVerifMapIntervalId);
mapTemp.dispatchAction({type: "downplay", seriesIndex: 0,}); mapTemp.dispatchAction({type: "downplay", seriesIndex: 0,});
mapTemp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,}); mapTemp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,});
mapTemp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,}); mapTemp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,});
}); });
// //
mapTemp.on('mouseout', () => { mapTemp?.on('mouseout', () => {
clearInterval(caseVerifMapIntervalId); // clearInterval(caseVerifMapIntervalId); //
caseVerifMapIntervalId = setInterval(caseVerifMapAnimation, 2000); caseVerifMapIntervalId = setInterval(caseVerifMapAnimation, 2000);
}); });
} }
const caseVerifTrendAnimationStop = () => { const caseVerifTrendAnimationStop = () => {
const temp = caseVerifProTrend?.value.getDom(); const temp = caseVerifProTrend?.value.getDom();
temp.addEventListener('mouseenter', () => { temp?.addEventListener('mouseenter', () => {
clearInterval(caseVerifTrendIntervalId); clearInterval(caseVerifTrendIntervalId);
}); });
temp.addEventListener('mouseleave', () => { temp?.addEventListener('mouseleave', () => {
clearInterval(caseVerifTrendIntervalId); clearInterval(caseVerifTrendIntervalId);
caseVerifTrendIntervalId = setInterval(caseVerifTrendAnimation, 1000); caseVerifTrendIntervalId = setInterval(caseVerifTrendAnimation, 1000);
}); });
} }
const caseVerifCaseSourceRateAnimationStop = () => { const caseVerifCaseSourceRateAnimationStop = () => {
const temp = caseSourceRate?.value?.chart; const temp = caseSourceRate?.value?.chart;
temp.on('mousemove', (e) => { temp?.on('mousemove', (e) => {
clearInterval(caseVerifCaseSourceIntervalId); clearInterval(caseVerifCaseSourceIntervalId);
temp.dispatchAction({type: "downplay", seriesIndex: 0,}); temp.dispatchAction({type: "downplay", seriesIndex: 0,});
temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,}); temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,});
temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,}); temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,});
}) })
temp.on('mouseout', () => { temp?.on('mouseout', () => {
clearInterval(caseVerifCaseSourceIntervalId); clearInterval(caseVerifCaseSourceIntervalId);
caseVerifCaseSourceIntervalId = setInterval(caseVerifCaseSourceRateAnimation, 2000); caseVerifCaseSourceIntervalId = setInterval(caseVerifCaseSourceRateAnimation, 2000);
}) })
} }
const caseVerifJbclSituationAnimationStop = () => { const caseVerifJbclSituationAnimationStop = () => {
const temp = jbclSituation?.value?.chart; const temp = jbclSituation?.value?.chart;
temp.on('mousemove', (e) => { temp?.on('mousemove', (e) => {
clearInterval(caseVerifJbclSituationIntervalId); clearInterval(caseVerifJbclSituationIntervalId);
temp.dispatchAction({type: "downplay", seriesIndex: 0,}); temp.dispatchAction({type: "downplay", seriesIndex: 0,});
temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,}); temp.dispatchAction({type: "highlight", seriesIndex: 0, dataIndex: e.dataIndex,});
temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,}); temp.dispatchAction({type: "showTip", seriesIndex: 0, dataIndex: e.dataIndex,});
}) })
temp.on('mouseout', () => { temp?.on('mouseout', () => {
clearInterval(caseVerifJbclSituationIntervalId); clearInterval(caseVerifJbclSituationIntervalId);
caseVerifJbclSituationIntervalId = setInterval(caseVerifJbclSituationAnimation, 2000); caseVerifJbclSituationIntervalId = setInterval(caseVerifJbclSituationAnimation, 2000);
}) })

4
src/views/datav/Jwpy.vue

@ -390,7 +390,7 @@ const handleOrgChange = async (checkedOrg) => {
if (chart) { if (chart) {
chart.dispatchAction({type: 'highlight', name: targetName,}); chart.dispatchAction({type: 'highlight', name: targetName,});
} else { } else {
alert("没有找到")
} }
console.log("年份" + selectYear.value + " 月份" + selectMonth.value + " 单位" + selectOrg.value + " task" + task.value) console.log("年份" + selectYear.value + " 月份" + selectMonth.value + " 单位" + selectOrg.value + " task" + task.value)
} catch (error) { } catch (error) {
@ -431,7 +431,7 @@ const handleChartClick = async (params) => {
// //
const discovery = async () => { const discovery = async () => {
// //
await GetZHMYLPM(selectYear.value, selectMonth.value, selectOrg.value, task.value, 2).then((res) => { await GetZHMYLPM(selectYear.value, selectMonth.value, selectOrg.value, task.value, 1).then((res) => {
tableData1.value = res[0].lstCity tableData1.value = res[0].lstCity
let temp = res[0].lstSheng; let temp = res[0].lstSheng;
// //

2398
src/views/datav/SceneInsp.vue

File diff suppressed because it is too large Load Diff

73
src/views/datav/VideoInsp.vue

@ -21,24 +21,19 @@
</div> </div>
</div> </div>
<div class="mb-12"> <div class="mb-12">
<iframe <VideoPlay :url="activeUrl" :showOperateBtns="false" />
:src="activeVideoUrl"
style="height: 180px"
></iframe>
</div> </div>
<el-scrollbar max-width="100%"> <el-scrollbar max-width="100%">
<div class="flex gap" style="width: 840px"> <div class="flex gap" style="width: 840px">
<div <div
v-for="item in videos" v-for="(item, index) in videos"
:key="item" :key="item"
@click="activeVideoUrl = item.url" @click="handlePlay(item, index)"
style="width: 160px" style="width: 160px"
> >
<img <img
:src="item.img" :src="item.imgUrl"
:active=" :active="activeVideoIndex === index"
activeVideoUrl === item.url
"
/> />
</div> </div>
</div> </div>
@ -67,7 +62,6 @@
<el-scrollbar height="280px"> <el-scrollbar height="280px">
<datav-chart-bar <datav-chart-bar
:data="jsdwRankList" :data="jsdwRankList"
:max="11"
size="large" size="large"
:color="colors" :color="colors"
/> />
@ -212,6 +206,8 @@
</template> </template>
<script setup> <script setup>
import LivePlayer from "@liveqing/liveplayer-v3";
import changshaMap from "@/assets/data/changsha.json"; import changshaMap from "@/assets/data/changsha.json";
import vCharts from "vue-echarts"; import vCharts from "vue-echarts";
import * as echarts from "echarts/core"; import * as echarts from "echarts/core";
@ -501,16 +497,16 @@ const getVideoSuperviseMapData = async (timeValue) => {
{ {
gte: 0, gte: 0,
lte: range60Percent, lte: range60Percent,
label: "低于最大问题的60%", label: "低于最大问题的60%",
color: "#4987F6", color: "#4987F6",
}, },
{ {
gte: range60Percent, gte: range60Percent,
lte: range80Percent, lte: range80Percent,
label: "介于最大问题的60%~80%", label: "介于最大问题的60%~80%",
color: "#F6A149", color: "#F6A149",
}, },
{ gte: range80Percent, label: "高于最大问题80%", color: "#D34343" }, { gte: range80Percent, label: "高于最大问题数的80%", color: "#D34343" },
]; ];
}; };
const getVideoSuperviseTrendData = async (year) => { const getVideoSuperviseTrendData = async (year) => {
@ -564,7 +560,7 @@ const videoMapAnimation = () => {
}); });
}; };
// 2 // 2
videoMapIntervalId = setInterval(videoMapAnimation, 2000); // videoMapIntervalId = setInterval(videoMapAnimation, 2000);
// //
const videoTrendAnimation = () => { const videoTrendAnimation = () => {
const trendTemp = videoProTrend?.value?.chart; const trendTemp = videoProTrend?.value?.chart;
@ -697,43 +693,34 @@ const videoProblemTypeRateAnimationStop = () => {
); );
}); });
}; };
// endregion
const videos = [
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000033.live.flv",
img: `/v2/imgs/video/1.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000028.live.flv",
img: `/v2/imgs/video/2.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000002.live.flv",
img: `/v2/imgs/video/3.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000019.live.flv",
img: `/v2/imgs/video/4.jpg`,
},
{
url: "http://65.47.6.105:18080/#/play/wasm/ws%3A%2F%2F65.47.6.105%3A8080%2Frtp%2F43012457021185000003_34020000001320000011.live.flv",
img: `/v2/imgs/video/5.jpg`,
},
];
const activeVideoUrl = ref(videos[0].url); import { listVideoConfigByDepartId } from '@/api/system/videoConfig'
const videos = ref([]);
const activeUrl = ref('');
const videoStatus = ref({ const videoStatus = ref({
all: 0, all: 0,
percentage: '0%', percentage: "0%",
on: 0 on: 0,
}); });
onMounted(() => { onMounted(() => {
getVideoStatus().then((data) => { getVideoStatus().then((data) => {
videoStatus.value = data; videoStatus.value = data;
}); });
listVideoConfigByDepartId('12630').then(data => {
videos.value = data;
if (data.length > 0) {
activeUrl.value = data[0].videoUrl
}
})
}); });
const activeVideoIndex = ref(0);
function handlePlay(item, index) {
activeVideoIndex.value = index;
activeUrl.value = item.videoUrl;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

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

@ -10,7 +10,7 @@
<el-scrollbar height="350px"> <el-scrollbar height="350px">
<datav-chart-bar <datav-chart-bar
:size="small" size="small"
:data="data1" :data="data1"
unit="%" unit="%"
remark-font-size="12px" remark-font-size="12px"

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

@ -253,7 +253,7 @@ const option = ref({
formatter: function (params) { formatter: function (params) {
console.log(params) console.log(params)
const dataItem = gobalTempMapVoList.value.find(item => item.name === params.name) || {}; // const dataItem = gobalTempMapVoList.value.find(item => item.name === params.name) || {}; //
console.log("Data item:", dataItem);
if (dataItem.name === params.name) { if (dataItem.name === params.name) {
return ` return `
<div class="tooltip"> <div class="tooltip">

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

@ -577,8 +577,7 @@ const option = ref({
position: 'bottom', position: 'bottom',
formatter: function (params) { formatter: function (params) {
const dataItem = mailMapIconList.value.find(item => item.name === params.name) || {}; // const dataItem = mailMapIconList.value.find(item => item.name === params.name) || {}; //
// console.log("Data item:", dataItem);
console.log("Data item:", mailMapIconList.value);
// //
if (dataItem.name === params.name) { if (dataItem.name === params.name) {
return ` return `

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

@ -58,7 +58,7 @@
<el-scrollbar height="350px"> <el-scrollbar height="350px">
<datav-chart-bar <datav-chart-bar
:data="fxsjChangedRankList" :data="fxsjChangedRankList"
:size="small" size="small"
title="整改率排名" title="整改率排名"
sub-title="已整改/问题数" sub-title="已整改/问题数"
unit="%" unit="%"
@ -113,7 +113,7 @@
<el-scrollbar height="350px"> <el-scrollbar height="350px">
<datav-chart-bar <datav-chart-bar
:data="jsdwChangedRankList" :data="jsdwChangedRankList"
:size="small" size="small"
title="整改率排名" title="整改率排名"
sub-title="已整改/问题数" sub-title="已整改/问题数"
unit="%" unit="%"
@ -964,7 +964,7 @@ const option = ref({
position: 'bottom', position: 'bottom',
formatter: function (params) { formatter: function (params) {
const dataItem = superviseTempMapVoList.value.find(item => item.name === params.name) || {}; // const dataItem = superviseTempMapVoList.value.find(item => item.name === params.name) || {}; //
console.log("Data item:", dataItem);
if (dataItem.name === params.name) { if (dataItem.name === params.name) {
return ` return `
<div class="tooltip"> <div class="tooltip">
@ -1217,8 +1217,8 @@ const getSubOneCheckBeerData = async (departId, times) => {
} }
const getSubOneWorkDynamicsData = async (departId, times) => { const getSubOneWorkDynamicsData = async (departId, times) => {
const res = await getSubOneWorkDynamics(departId, times); const data = await getSubOneWorkDynamics(departId, times);
const colorNewsVoList = workDynamicColorMapping(res.newsVoList); const colorNewsVoList = workDynamicColorMapping(data);
messages.value = colorNewsVoList; messages.value = colorNewsVoList;
} }
const getData = async () => { const getData = async () => {

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

File diff suppressed because it is too large Load Diff

13
src/views/rightsComfort/Comfort.vue

@ -30,6 +30,18 @@
<depart-tree-select v-model="query.departId" /> <depart-tree-select v-model="query.departId" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6">
<el-form-item label="状态">
<el-select v-model="query.rpcStatus">
<el-option
v-for="item in dict.comfortStatus"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
<div class="flex end"> <div class="flex end">
@ -67,6 +79,7 @@
width="100" width="100"
/> />
<el-table-column label="申请人单位" prop="departName" /> <el-table-column label="申请人单位" prop="departName" />
<el-table-column label="主办单位" prop="handleDepartName" />
<el-table-column label="开户行"> <el-table-column label="开户行">
<template #default="{ row }"> <template #default="{ row }">
<span>{{ row.bankCard }}</span> <span>{{ row.bankCard }}</span>

445
src/views/rightsComfort/ComfortPacks.vue

@ -0,0 +1,445 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="呈报时间">
<date-time-range-picker-ext
v-model="query.reportTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="呈报说明">
<el-input
v-model="query.reportTitle"
placeholder="请输入"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="flex between">
<el-button type="primary" @click="handleAdd">
<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="reportTitle"
show-overflow-tooltip
/>
<el-table-column
label="呈报人数"
prop="reportNum"
align="center"
/>
<el-table-column label="呈报金额" prop="reportMoney" />
<el-table-column label="呈报时间" prop="reportTime" />
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button
link
type="primary"
@click="handleShowDetail(row)"
>查看</el-button
>
<el-button link type="primary" @click="download(row)"
>下载呈报件</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
v-model="show"
title="新增抚慰金呈报"
width="70vw"
top="3vh"
style="margin-bottom: 0"
>
<el-table
:data="comforts"
style="height: 500px"
ref="comfortTableRef"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
:reserve-selection="false"
width="55"
/>
<el-table-column
label="抚慰编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column label="申请时间" prop="applyDate" width="160" />
<el-table-column label="事发时间" prop="happenTime" width="160" />
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column
label="受伤程度"
prop="injurySeverityName"
width="120"
/>
<el-table-column
label="抚慰金额"
prop="injurySeverity"
width="100"
align="center"
>
<template #default="{ row }">
<span v-if="row.injurySeverity"
>{{ row.injurySeverity }}</span
>
</template>
</el-table-column>
<el-table-column label="状态" width="100">
<template #default="{ row }">
<el-tag type="primary">{{
getDictLable(dict.comfortStatus, row.rpcStatus)
}}</el-tag>
</template>
</el-table-column>
</el-table>
<div class="flex end mt-8 mb-20">
<el-pagination
@size-change="getComfort"
@current-change="getComfort"
:page-sizes="[10, 20, 50]"
v-model:page-size="comfortQuery.size"
v-model:current-page="comfortQuery.current"
layout="total, sizes, prev, pager, next"
:total="comfortTotal"
>
</el-pagination>
</div>
<el-form label-width="160" ref="formRef" :model="formData">
<el-form-item
label="呈报人数"
prop="comforts"
:rules="{
required: true,
validator: validateComforts,
}"
>
<span>{{ formData.comforts.length }}</span>
</el-form-item>
<el-form-item label="呈报金额">
{{
formData.comforts.length > 0
? formData.comforts
.map((item) => parseInt(item.injurySeverity))
.reduce((a, b) => a + b, 0)
: 0
}}
</el-form-item>
<el-form-item
label="呈报说明"
prop="reportTitle"
:rules="{
required: true,
message: '请输入呈报说明',
}"
>
<el-input
type="textarea"
v-model="formData.reportTitle"
clearable
/>
</el-form-item>
</el-form>
<footer class="flex end mt-20">
<el-button size="large">取消</el-button>
<el-button
type="primary"
size="large"
@click="handleSubmit"
:disabled="disabled"
>提交呈报</el-button
>
</footer>
</el-dialog>
<el-dialog
v-model="detailShow"
title="抚慰金呈报详情"
width="70vw"
top="3vh"
style="margin-bottom: 0"
>
<div style="min-height: 500px">
<div class="table-container mb-40">
<el-table
:data="comfortPack.comforts"
style="max-height: 500px"
>
<el-table-column
label="抚慰编号"
prop="number"
show-overflow-tooltip
/>
<el-table-column
label="申请时间"
prop="applyDate"
width="160"
/>
<el-table-column
label="事发时间"
prop="happenTime"
width="160"
/>
<el-table-column
label="申请人姓名"
prop="applicantEmpName"
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column
label="受伤程度"
prop="injurySeverityName"
width="120"
/>
<el-table-column
label="抚慰金额"
prop="injurySeverity"
width="100"
align="center"
>
<template #default="{ row }">
<span v-if="row.injurySeverity"
>{{ row.injurySeverity }}</span
>
</template>
</el-table-column>
<el-table-column
label="操作"
width="100"
>
<template #default="{ row }">
<el-button
link
type="primary"
@click="handleComfortShow(row)"
>查看</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="row">
<div class="col col-12">
<label>呈报人数</label>
<span>{{ comfortPack.reportNum }}</span>
</div>
<div class="col col-12">
<label>呈报金额</label>
<span>{{ comfortPack.reportMoney }}</span>
</div>
<div class="col col-24">
<label>呈报说明</label>
<span>{{ comfortPack.reportTitle }}</span>
</div>
</div>
</div>
</el-dialog>
<comfort-dialog v-model:show="actionShow" :id="activeRpcId" />
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
import moment from "moment";
import {
listComfortPacks,
addComfortPacks,
getComfortPacks,
} from "@/api/rightsComfort/comfortPacks";
import { listComfort } from "@/api/rightsComfort/comfort";
import { listPolice } from "@/api/system/police";
import { getDictLable } from "@/utils/util";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
import { nextTick } from "vue";
const catchStore = useCatchStore();
const dict = catchStore.getDicts(["comfortStatus"]);
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listComfortPacks(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
getList();
const actionShow = ref(false);
const activeRpcId = ref('');
async function handleComfortShow(row) {
actionShow.value = true;
activeRpcId.value = row.rpcId;
}
const show = ref(false);
const comforts = ref([]);
const comfortQuery = ref({
current: 1,
size: 10,
rpcStatus: "to_be_reported",
});
const comfortTableRef = ref();
const comfortTotal = ref(0);
async function handleAdd() {
show.value = true;
await getComfort();
}
let lock = false;
async function getComfort() {
const data = await listComfort(comfortQuery.value);
comforts.value = data.records;
comfortTotal.value = data.total;
nextTick(() => {
lock = true;
comforts.value.forEach((item) => {
if (formData.value.comforts.some((o) => o.rpcId === item.rpcId)) {
comfortTableRef.value.toggleRowSelection(item, true);
}
});
lock = false;
});
}
const formRef = ref();
const formData = ref({
comforts: [],
});
function handleSelectionChange(selection) {
if (lock) {
return;
}
selection.forEach((item) => {
if (!formData.value.comforts.some((o) => o.rpcId === item.rpcId)) {
formData.value.comforts.push(item);
}
});
comforts.value
.filter((item) => !selection.some((o) => o.rpcId === item.rpcId))
.forEach((item) => {
const obj = formData.value.comforts.find(
(o) => o.rpcId === item.rpcId
);
if (obj) {
formData.value.comforts.splice(
formData.value.comforts.indexOf(obj),
1
);
}
});
}
function validateComforts(rule, value, cb) {
if (value.length === 0) {
cb(new Error("请选择呈报人"));
} else {
cb();
}
}
const disabled = ref(false);
async function handleSubmit() {
await formRef.value.validate();
disabled.value = true;
try {
await addComfortPacks(formData.value);
} catch (e) {
disabled.value = false;
return;
}
disabled.value = false;
formData.value = {
comforts: [],
};
show.value = false;
getList();
feedback.msgSuccess("操作成功");
}
function download(row) {
window.open(`${BASE_PATH}/file/stream/${row.reportZip}`);
}
const detailShow = ref(false);
const comfortPack = ref({
comforts: [],
});
const detailLoading = ref(false);
async function handleShowDetail(row) {
detailShow.value = true;
detailLoading.value = true;
comfortPack.value = await getComfortPacks(row.id);
detailLoading.value = false;
}
</script>
<style lang="scss" scoped>
h5 {
margin: 10px 0;
}
</style>

514
src/views/rightsComfort/MyComfort.vue

@ -83,12 +83,20 @@
</el-table-column> </el-table-column>
<el-table-column label="状态" width="100"> <el-table-column label="状态" width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-tag type="primary" v-if="row.rpcStatus">{{ <el-tag
getDictLable( :type="
dict.comfortStatus, row.rpcStatus !== 'returned'
row.rpcStatus ? 'primary'
) : 'danger'
}}</el-tag> "
v-if="row.rpcStatus"
>{{
getDictLable(
dict.comfortStatus,
row.rpcStatus
)
}}</el-tag
>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="200"> <el-table-column label="操作" width="200">
@ -97,8 +105,30 @@
link link
type="primary" type="primary"
@click="handleShow(row, false)" @click="handleShow(row, false)"
v-if="row.rpcStatus !== 'returned'"
>立即处理</el-button >立即处理</el-button
> >
<template v-else>
<el-button
link
type="primary"
@click="handleShow(row, true)"
>查看</el-button
>
<el-button
link
type="primary"
@click="handleReSubmit(row)"
>重新提交</el-button
>
<el-button
link
type="danger"
v-if="row.rpcStatus === 'returned'"
@click="handleDelete(row)"
>删除</el-button
>
</template>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -154,7 +184,12 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" width="200"> <el-table-column label="操作" width="200">
<template #default="{ row }"> <template #default="{ row }">
<el-button link type="primary" @click="handleShow(row, true)">查看</el-button> <el-button
link
type="primary"
@click="handleShow(row, true)"
>查看</el-button
>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -182,8 +217,13 @@
top="2vh" top="2vh"
style="margin-bottom: 0" style="margin-bottom: 0"
> >
<el-scrollbar max-height="calc(96vh - 130px)"> <el-scrollbar height="calc(96vh - 130px)">
<el-form :label-width="140" ref="formRef" :model="formData"> <el-form
:label-width="140"
ref="formRef"
:model="formData"
v-if="step === 0"
>
<h5>办理信息</h5> <h5>办理信息</h5>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
@ -215,9 +255,14 @@
prop="handleDepartId" prop="handleDepartId"
> >
<div style="width: 300px"> <div style="width: 300px">
<depart-tree-select <el-tree-select
v-model="formData.handleDepartId" v-model="formData.handleDepartId"
:check-strictly="true" :data="departs"
:props="{ label: 'shortName', value: 'id' }"
node-key="id"
:default-expanded-keys="['12630']"
clearable
filterable
@node-click=" @node-click="
(node) => (node) =>
(formData.handleDepartName = (formData.handleDepartName =
@ -239,9 +284,12 @@
}" }"
prop="" prop=""
> >
<el-radio-group v-model="formData.isSelf"> <el-radio-group
<el-radio :value="1"></el-radio> v-model="formData.isSelf"
<el-radio :value="0"></el-radio> @change="handleSelectIsSelf"
>
<el-radio value="1"></el-radio>
<el-radio value="0"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -261,43 +309,22 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="formData.isSelf === 0"> <el-col :span="12" v-if="formData.isSelf === '0'">
<el-form-item <el-form-item
label="代理人姓名" label="代理人姓名"
:rules="{ :rules="{
required: true, required: true,
trigger: ['blur'], message: '请输入代理人姓名',
}" }"
prop="" prop="agentName"
> >
<el-input <el-input
style="width: 300px" style="width: 300px"
v-model="formData.agentName"
placeholder="请输入" placeholder="请输入"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="formData.isSelf === 0">
<el-form-item
label="代理人单位"
:rules="{
required: true,
trigger: ['blur'],
}"
prop=""
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.handleDepartId"
:check-strictly="true"
@node-click="
(node) =>
(formData.handleDepartName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
</el-row> </el-row>
<h5>申请人信息</h5> <h5>申请人信息</h5>
<el-row> <el-row>
@ -362,6 +389,82 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item
label="身份证号码"
:rules="{
required: true,
message: '请输入',
}"
prop="idCode"
>
<el-input
v-model="formData.idCode"
clearable
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="单位"
:rules="{
required: true,
message: '请选择',
}"
prop="departId"
>
<div style="width: 300px">
<depart-tree-select
v-model="formData.departId"
:check-strictly="true"
@node-click="
(node) =>
(formData.departName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="警号"
:rules="{
required: true,
message: '请输入',
}"
prop="empNo"
>
<el-input
v-model="formData.empNo"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职务" prop="job">
<el-input
v-model="formData.job"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="警衔" prop="policeRank">
<el-input
v-model="formData.policeRank"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
label="文化程度" label="文化程度"
@ -407,106 +510,54 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item-ext
label="身份证号码"
:rules="{
required: true,
message: '请输入',
}"
prop="idCode"
>
<el-input
v-model="formData.idCode"
clearable
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="联系电话" label="联系电话"
:rules="{ :rules="{
required: true, required: true,
message: '请输入', message: '请输入',
}" }"
prop="mobile" prop="mobile"
content="银行预留电话"
> >
<el-input <el-input
v-model="formData.mobile" v-model="formData.mobile"
style="width: 300px" style="width: 300px"
placeholder="请输入" placeholder="请输入银行预留电话"
/> />
</el-form-item> </el-form-item-ext>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
label="单位" label="开户行"
prop="bankCard"
:rules="{ :rules="{
required: true, required: true,
message: '请选择', message: '请选择',
}" }"
prop="departId"
> >
<div style="width: 300px"> <el-select
<depart-tree-select v-model="formData.bankCard"
v-model="formData.departId" clearable
:check-strictly="true"
@node-click="
(node) =>
(formData.departName =
node.shortName)
"
/>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="职务" prop="job">
<el-input
v-model="formData.job"
style="width: 300px" style="width: 300px"
placeholder="请输入" >
/> <el-option
v-for="item in dict.bank"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
label="警号" label="所属支行"
prop="bankBranch"
:rules="{ :rules="{
required: true, required: true,
message: '请输入', message: '请输入',
}" }"
prop="empNo"
> >
<el-input
v-model="formData.empNo"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="警衔" prop="policeRank">
<el-input
v-model="formData.policeRank"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开户行" prop="bankCard">
<el-input
v-model="formData.bankCard"
style="width: 300px"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属支行" prop="bankBranch">
<el-input <el-input
v-model="formData.bankBranch" v-model="formData.bankBranch"
style="width: 300px" style="width: 300px"
@ -515,7 +566,14 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="银行账号" prop="bankCardAccount"> <el-form-item
label="银行账号"
prop="bankCardAccount"
:rules="{
required: true,
message: '请输入',
}"
>
<el-input <el-input
v-model="formData.bankCardAccount" v-model="formData.bankCardAccount"
style="width: 300px" style="width: 300px"
@ -653,20 +711,6 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item
label="办案单位"
prop=""
:rules="{
required: true,
message: '请选择',
}"
>
<div style="width: 300px">
<depart-tree-select :check-strictly="true" />
</div>
</el-form-item>
</el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
label="侵权人姓名" label="侵权人姓名"
@ -702,13 +746,12 @@
</el-row> </el-row>
<el-divider /> <el-divider />
<h5>佐证材料</h5> <h5>佐证材料</h5>
<el-row> <el-form-item label="附件" prop="documentFile">
<el-col :span="12"> <file-upload
<el-form-item label="附件" prop="documentFile"> v-model:files="formData.documentFile"
<file-upload v-model:files="formData.documentFile" /> tips="1、事情经过(盖章)。2、受伤照片。3、伤情鉴定。4、受立案登记表。5、其他。"
</el-form-item> />
</el-col> </el-form-item>
</el-row>
<el-divider /> <el-divider />
<h5>呈报审批</h5> <h5>呈报审批</h5>
<el-row> <el-row>
@ -727,27 +770,53 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<div v-else style="height: 60vh" class="flex center">
<el-result
icon="success"
title="申请成功"
sub-title="请在我的已办查看进度"
>
</el-result>
</div>
</el-scrollbar> </el-scrollbar>
<footer class="flex end"> <footer class="flex end" v-if="step === 0">
<el-button @click="show = false" size="large">取消</el-button> <el-button @click="show = false" size="large">取消</el-button>
<el-button type="primary" @click="submit" size="large" <el-button
type="primary"
@click="submit"
size="large"
:disabled="btDisabled"
>确定</el-button >确定</el-button
> >
</footer> </footer>
</el-dialog> </el-dialog>
<comfort-dialog v-model:show="actionShow" :id="activeRpcId" :disabled="dialogDisabled" /> <comfort-dialog
v-model:show="actionShow"
:id="activeRpcId"
:disabled="dialogDisabled"
@update="search()"
/>
</template> </template>
<script setup> <script setup>
import moment from "moment"; import moment from "moment";
import { listTodos, listDone, applyComfort } from "@/api/rightsComfort/comfort"; import {
listComfortTodos,
listDone,
applyComfort,
updateComfort,
delComfort,
getDetail,
} from "@/api/rightsComfort/comfort";
import { listPolice } from "@/api/system/police"; import { listPolice } from "@/api/system/police";
import { listRightPersonByDepartId } from "@/api/system/rightPerson"; import { listRightPersonByDepartId } from "@/api/system/rightPerson";
import { getDictLable } from "@/utils/util"; import { secondList } from "@/api/system/depart";
import { getDictLable, getGenderFromIdCode } from "@/utils/util";
import feedback from "@/utils/feedback"; import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
import { onMounted } from "vue"; import useUserStore from "@/stores/modules/user";
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts([ const dict = catchStore.getDicts([
@ -755,11 +824,10 @@ const dict = catchStore.getDicts([
"injurySeverity", "injurySeverity",
"incidentLink", "incidentLink",
"comfortStatus", "comfortStatus",
"bank",
]); ]);
const query = ref({ const query = ref({});
});
const todos = ref([]); const todos = ref([]);
const todoPage = reactive({ const todoPage = reactive({
@ -768,7 +836,7 @@ const todoPage = reactive({
size: 10, size: 10,
}); });
const dones = ref([]) const dones = ref([]);
const donePage = reactive({ const donePage = reactive({
total: 0, total: 0,
current: 1, current: 1,
@ -776,19 +844,19 @@ const donePage = reactive({
}); });
function getTodos() { function getTodos() {
const queryParam = {...query.value} const queryParam = { ...query.value };
queryParam.current = todoPage.current queryParam.current = todoPage.current;
queryParam.size = todoPage.size queryParam.size = todoPage.size;
listTodos(queryParam).then((data) => { listComfortTodos(queryParam).then((data) => {
todos.value = data.records; todos.value = data.records;
todoPage.total = data.total; todoPage.total = data.total;
}); });
} }
function getDones() { function getDones() {
const queryParam = {...query.value} const queryParam = { ...query.value };
queryParam.current = donePage.current queryParam.current = donePage.current;
queryParam.size = donePage.size queryParam.size = donePage.size;
listDone(queryParam).then((data) => { listDone(queryParam).then((data) => {
dones.value = data.records; dones.value = data.records;
donePage.total = data.total; donePage.total = data.total;
@ -801,18 +869,22 @@ function reset() {
size: 10, size: 10,
}; };
getTodos(); getTodos();
getDones() getDones();
} }
function search() { function search() {
getTodos() getTodos();
getDones() getDones();
} }
const departs = ref([]);
onMounted(() => { onMounted(() => {
getTodos(); getTodos();
getDones() getDones();
}) secondList().then((data) => {
departs.value = data;
});
});
const show = ref(false); const show = ref(false);
const formData = ref({ const formData = ref({
@ -820,22 +892,83 @@ const formData = ref({
}); });
const formRef = ref(null); const formRef = ref(null);
function submit() { const btDisabled = ref(false);
formRef.value.validate((flag) => { const step = ref(0);
if (flag) { async function submit() {
applyComfort(formData.value).then(() => { try {
feedback.msgSuccess("操作成功"); await formRef.value.validate();
show.value = false; } catch (e) {
formData.value = { feedback.msgWarning("请检查输入项");
applyDate: moment().format("YYYY-MM-DD"), return;
}; }
getDones() btDisabled.value = true;
}); if (mode.value === "add") {
} await applyComfort(formData.value);
}); } else {
updateComfort(formData.value);
getTodos();
}
step.value = 1;
show.value = false;
formData.value = {
applyDate: moment().format("YYYY-MM-DD"),
};
getDones();
btDisabled.value = false;
formRef.value.resetFields();
} }
const mode = ref("add");
function handleShowAdd() { function handleShowAdd() {
step.value = 0;
mode.value = "add";
show.value = true;
}
async function handleReSubmit(row) {
const data = await getDetail(row.rpcId);
formData.value = {
rpcId: data.apply.rpcId,
applyDate: data.apply.applyDate,
happenTime: data.apply.happenTime,
applicantEmpName: data.apply.applicantEmpName,
handleDepartId: data.apply.handleDepartId,
handleDepartName: data.apply.handleDepartName,
isSelf: data.apply.isSelf,
relation: data.apply.relation,
agentName: data.apply.agentName,
departId: data.apply.departId,
departName: data.apply.departName,
happenTime: data.apply.happenTime,
factReason: data.apply.factReason,
incidentLink: data.apply.incidentLink,
incidentLinkName: data.apply.incidentLinkName,
formsOfTort: data.apply.formsOfTort,
formsOfTortName: data.apply.formsOfTortName,
infringerName: data.apply.infringerName,
infringerHandle: data.apply.infringerHandle,
documentFile: data.apply.documentFile
? JSON.parse(data.apply.documentFile)
: [],
sex: data.person.sex,
birthday: data.person.birthday,
idCode: data.person.idCode,
empNo: data.person.empNo,
job: data.person.job,
policeRank: data.person.policeRank,
politicCountenance: data.person.politicCountenance,
mobile: data.person.mobile,
bankCard: data.person.bankCard,
bankBranch: data.person.bankBranch,
bankCardAccount: data.person.bankCardAccount,
levelEducation: data.person.levelEducation,
injurySeverity: data.applyPerson.injurySeverity,
injurySeverityName: data.applyPerson.injurySeverityName,
};
mode.value = "edit";
show.value = true; show.value = true;
} }
@ -862,8 +995,10 @@ watch(
(val) => { (val) => {
listRightPersonByDepartId(val).then((data) => { listRightPersonByDepartId(val).then((data) => {
if (data.length) { if (data.length) {
formData.value.approverEmpNo = data.map(item => item.empNo) formData.value.approverEmpNo = data.map((item) => item.empNo);
formData.value.approver = data.map(item => item.empName).join('、') formData.value.approver = data
.map((item) => item.empName)
.join("、");
} else { } else {
delete formData.value.approverEmpNo; delete formData.value.approverEmpNo;
delete formData.value.approver; delete formData.value.approver;
@ -873,19 +1008,46 @@ watch(
); );
const actionShow = ref(false); const actionShow = ref(false);
const activeRpcId = ref(false) const activeRpcId = ref(false);
const dialogDisabled = ref(true) const dialogDisabled = ref(true);
function handleShow(row, disabled) { function handleShow(row, disabled) {
actionShow.value = true actionShow.value = true;
activeRpcId.value = row.rpcId activeRpcId.value = row.rpcId;
dialogDisabled.value = disabled dialogDisabled.value = disabled;
} }
const handleDelete = async (row) => {
await feedback.confirm(`确定要删除 ${row.number}`);
await delComfort(row.rpcId);
feedback.msgSuccess("删除成功");
getTodos();
};
const userStore = useUserStore();
function handleSelectIsSelf() {
if (formData.value.isSelf === "1") {
formData.value.applicantEmpName = userStore.user.nickName;
formData.value.idCode = userStore.user.userName;
formData.value.empNo = userStore.user.empNo;
formData.value.mobile = userStore.user.mobile;
formData.value.departId = userStore.user.departId;
const sex = getGenderFromIdCode(formData.value.idCode);
if (sex) {
formData.value.sex = sex === "男" ? 0 : 1;
}
if (formData.value.idCode && formData.value.idCode.length === 18) {
formData.value.birthday = moment(
formData.value.idCode.substring(6, 14),
"YYYYMMDD"
).format("YYYY-MM-DD");
}
}
}
const resultShow = ref(true);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
h5 { h5 {
margin: 10px 0; margin: 10px 0;
} }
</style> </style>

82
src/views/rightsComfort/Rights.vue

@ -47,29 +47,28 @@
<div class="table-container"> <div class="table-container">
<el-table :data="list"> <el-table :data="list">
<el-table-column <el-table-column
label="维权编号" label="申请人姓名"
prop="number" prop="applicantEmpName"
show-overflow-tooltip width="100"
/> />
<el-table-column <el-table-column
label="申请时间" label="申请人警号"
prop="applyDate" prop="applicantEmpNo"
width="160" width="100"
/> />
<el-table-column <el-table-column
label="事发时间" label="事发时间"
prop="happenTime" prop="happenTime"
width="160" width="160"
/> />
<el-table-column <el-table-column label="申请人单位" prop="departName" width="180" show-overflow-tooltip />
label="申请人姓名" <el-table-column label="案件编号" prop="caseNumber" width="200" />
prop="applicantEmpName" <el-table-column label="案件经过" prop="factReason" show-overflow-tooltip />
width="100"
/>
<el-table-column label="申请人单位" prop="departName" />
<el-table-column label="状态" width="100"> <el-table-column label="状态" width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-tag type="primary">{{
getDictLable(dict.comfortStatus, row.rpcStatus)
}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="200"> <el-table-column label="操作" width="200">
@ -77,13 +76,13 @@
<el-button <el-button
link link
type="primary" type="primary"
@click="handleShow(row)" @click="handleDetail(row)"
>查看</el-button >查看</el-button
> >
<el-button <el-button
link link
type="danger" type="danger"
@click="handleShow(row)" @click="handleDelete(row)"
>删除</el-button >删除</el-button
> >
</template> </template>
@ -104,10 +103,49 @@
</div> </div>
</div> </div>
<el-dialog title="维权详情" v-model="show" width="50vw">
<div class="dialog-container">
<div class="row mt-10">
<div class="col col-12">
<label>申请人姓名</label>
<span>{{ activeRow.applicantEmpName }}</span>
</div>
<div class="col col-12">
<label>申请人警号</label>
<span>{{ activeRow.applicantEmpNo }}</span>
</div>
<div class="col col-12">
<label>事发时间</label>
<span>{{ activeRow.happenTime }}</span>
</div>
<div class="col col-12">
<label>案件编号</label>
<span>{{ activeRow.caseNumber || '/' }}</span>
</div>
<div class="col col-12">
<label>状态</label>
<span>{{
getDictLable(
dict.comfortStatus,
activeRow.rpcStatus
)
}}</span>
</div>
</div>
<div class="row mt-10" style="margin-bottom: 60px">
<div class="col col-24">
<label>案件经过</label>
<span>{{ activeRow.factReason }}</span>
</div>
</div>
</div>
</el-dialog>
</template> </template>
<script setup> <script setup>
import moment from "moment"; import moment from "moment";
import { listRights } from "@/api/rightsComfort/rights"; import { listRights } from "@/api/rightsComfort/rights";
import { delComfort } from "@/api/rightsComfort/comfort";
import { listPolice } from "@/api/system/police"; import { listPolice } from "@/api/system/police";
import { getDictLable } from "@/utils/util"; import { getDictLable } from "@/utils/util";
import feedback from "@/utils/feedback"; import feedback from "@/utils/feedback";
@ -116,9 +154,6 @@ import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts([ const dict = catchStore.getDicts([
"formsOfTort",
"injurySeverity",
"incidentLink",
"comfortStatus" "comfortStatus"
]); ]);
@ -154,11 +189,18 @@ function handleShow(row) {
} }
const handleDelete = async (row) => { const handleDelete = async (row) => {
await feedback.confirm(`确定要删除 ${row.number}`); await feedback.confirm(`确定要删除该数据`);
// await delComfort(row.rpcId); await delComfort(row.rpcId);
feedback.msgSuccess("删除成功"); feedback.msgSuccess("删除成功");
getList(); getList();
}; };
const activeRow = ref({})
const show = ref(false)
const handleDetail = (row) => {
activeRow.value = row
show.value = true
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
h5 { h5 {

4
src/views/sensitivePerception/Model.vue

@ -837,11 +837,11 @@
" "
> >
<el-form-item <el-form-item
label="通知单位" label="办理单位类型"
prop="handleDepartType" prop="handleDepartType"
:rules="{ :rules="{
required: true, required: true,
message: '请选择通知单位', message: '请选择办理单位类型',
}" }"
> >
<div> <div>

28
src/views/sensitivePerception/ModelClue.vue

@ -104,7 +104,7 @@
<el-table-column <el-table-column
label="涉及人员" label="涉及人员"
prop="involvePoliceName" prop="involvePoliceName"
width="100" width="160"
> >
<template #default="{ row }"> <template #default="{ row }">
<div v-if="row.involvePoliceName"> <div v-if="row.involvePoliceName">
@ -193,18 +193,18 @@
</el-row> </el-row>
</div> </div>
<el-dialog title="预警线索数据详情" v-model="show" width="80vw"> <el-dialog title="预警线索数据详情" v-model="show" width="50vw">
<div class="dialog-container"> <div class="dialog-container">
<div class="row mt-10"> <div class="row mt-10">
<div class="col col-6"> <div class="col col-12">
<label>预警时间</label> <label>预警时间</label>
<span>{{ activeModelClue.createTime }}</span> <span>{{ activeModelClue.createTime }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-12">
<label>预警模型</label> <label>预警模型</label>
<span>{{ activeModelClue.modelName }}</span> <span>{{ activeModelClue.modelName }}</span>
</div> </div>
<div class="col col-6"> <div class="col col-12">
<label>涉及单位</label> <label>涉及单位</label>
<span> <span>
<span>{{ <span>{{
@ -221,15 +221,7 @@
<label>涉及人员</label> <label>涉及人员</label>
<span>{{ activeModelClue.involvePoliceName }}</span> <span>{{ activeModelClue.involvePoliceName }}</span>
</div> </div>
</div> <div class="col col-12">
<div class="row mt-10">
<div class="col col-24">
<label>预警内容</label>
<span>{{ activeModelClue.thingDesc }}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-6">
<label>分发状态</label> <label>分发状态</label>
<span>{{ <span>{{
getDictLable( getDictLable(
@ -239,9 +231,11 @@
}}</span> }}</span>
</div> </div>
</div> </div>
<h3>详细信息</h3> <div class="row mt-10" style="margin-bottom: 60px">
<div style="min-height: 200px"> <div class="col col-24">
<el-empty description="无数据" /> <label>预警内容</label>
<span>{{ activeModelClue.thingDesc }}</span>
</div>
</div> </div>
</div> </div>
</el-dialog> </el-dialog>

29
src/views/sensitivePerception/ModelClueManual.vue

@ -1,10 +1,10 @@
<template> <template>
<div class="container h100"> <div class="container h100">
<el-row :gutter="20" class="h100"> <el-row :gutter="20" class="h100">
<el-col :span="4"> <el-col :span="6">
<model-tree v-model="query.modelIds" /> <model-tree v-model="query.modelIds" />
</el-col> </el-col>
<el-col :span="20"> <el-col :span="18">
<header> <header>
<el-form :label-width="140"> <el-form :label-width="140">
<el-row> <el-row>
@ -62,8 +62,8 @@
</div> </div>
</div> </div>
</header> </header>
<div class="table-container"> <div class="table-container" v-loading="loading">
<el-table :data="list" ref="tableRef"> <el-table :data="list" ref="tableRef" max-height="600">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column <el-table-column
label="预警时间" label="预警时间"
@ -168,7 +168,7 @@
<el-pagination <el-pagination
@size-change="getList" @size-change="getList"
@current-change="getList" @current-change="getList"
:page-sizes="[9, 18, 36]" :page-sizes="[10, 20, 50, 100]"
v-model:page-size="query.size" v-model:page-size="query.size"
v-model:current-page="query.current" v-model:current-page="query.current"
layout="total, sizes, prev, pager, next" layout="total, sizes, prev, pager, next"
@ -180,13 +180,13 @@
</el-row> </el-row>
</div> </div>
<el-dialog title="问题分发" v-model="manualShow" width="80vw" top="5vh"> <el-dialog title="问题分发" v-model="manualShow" width="80vw" top="5vh" style="margin-bottom: 0">
<header> <header>
<el-form :label-width="140"> <el-form :label-width="140">
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="模型"> <el-form-item label="模型">
<el-select v-model="manualQuery.modelId"> <el-select v-model="manualQuery.modelId" clearable>
<el-option <el-option
v-for="item in modelOptions" v-for="item in modelOptions"
:key="item.value" :key="item.value"
@ -201,6 +201,7 @@
<depart-tree-select <depart-tree-select
v-model="manualQuery.involveDepartId" v-model="manualQuery.involveDepartId"
:check-strictly="false" :check-strictly="false"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -229,7 +230,8 @@
</header> </header>
<div style="min-height: 500px"> <div style="min-height: 500px">
<div class="table-container"> <div class="table-container">
<el-table :data="filterManualList"> <el-table :data="filterManualList" max-height="580">
<el-table-column type="index" width="50" />
<el-table-column <el-table-column
label="预警时间" label="预警时间"
prop="createTime" prop="createTime"
@ -299,7 +301,7 @@
</footer> </footer>
</el-dialog> </el-dialog>
<el-dialog title="任务分发" v-model="distributeShow" width="50vw" top="5vh"> <el-dialog title="任务分发" v-model="distributeShow" width="50vw" top="2vh" style="margin-bottom: 0">
<el-form :label-width="120" ref="formRef" :model="form" v-loading="submitLoading"> <el-form :label-width="120" ref="formRef" :model="form" v-loading="submitLoading">
<el-form-item <el-form-item
label="任务名称" label="任务名称"
@ -334,7 +336,9 @@
trigger: ['blur'], trigger: ['blur'],
}" }"
> >
<el-select v-model="form.businessTypeCode" style="width: 280px"> <el-select v-model="form.businessTypeCode" style="width: 280px" @change="(val) => form.businessTypeCode = dict.businessType.filter(
(item) => item.dictValue === val
)[0].dictLabel">
<el-option <el-option
v-for="item in dict.businessType" v-for="item in dict.businessType"
:key="item.id" :key="item.id"
@ -561,10 +565,13 @@ watch(
} }
); );
const loading = ref(false)
function getList() { function getList() {
loading.value = true
listModelClue(query.value).then((data) => { listModelClue(query.value).then((data) => {
list.value = data.records; list.value = data.records;
total.value = data.total; total.value = data.total;
loading.value = false
}); });
} }
@ -640,6 +647,8 @@ function handleShowDistributeDialog() {
return; return;
} }
distributeShow.value = true; distributeShow.value = true;
console.log(filterManualList.value)
form.value.taskName = filterManualList.value[0].modelName
} }
const form = ref({ const form = ref({

2
src/views/sensitivePerception/ModelClueTask.vue

@ -105,7 +105,7 @@
<el-pagination <el-pagination
@size-change="getList" @size-change="getList"
@current-change="getList" @current-change="getList"
:page-sizes="[9, 18, 36]" :page-sizes="[10, 20, 50, 100]"
v-model:page-size="query.size" v-model:page-size="query.size"
v-model:current-page="query.current" v-model:current-page="query.current"
layout="total, sizes, prev, pager, next" layout="total, sizes, prev, pager, next"

251
src/views/system/HandleResultMaping.vue

@ -0,0 +1,251 @@
<template>
<div class="container">
<header>
<el-row>
<el-col :span="12">
<div class="form-row flex">
<label class="text-center">局长信箱</label>
<div class="flex wrap query-box">
<el-input
placeholder="处理结果"
v-model="query.originId"
clearable
style="width: 280px"
/>
</div>
</div>
</el-col>
<el-col :span="12">
<div class="form-row flex">
<label class="text-center">数字督察</label>
<div class="flex wrap query-box">
<el-select
v-model="query.handleResultCode"
style="width: 280px"
clearable
>
<el-option
v-for="item in dict.handleResult"
:key="item.dictCode"
:value="item.dictValue"
:label="item.dictLabel"
/>
</el-select>
</div>
</div>
</el-col>
</el-row>
<div class="flex between mt-20 mb-26">
<el-button type="primary" @click="handleAdd">
<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="externalName" />
<el-table-column label="数字督察处理结果" prop="internalName" />
<el-table-column
label="最后修改时间"
prop="updateTime"
width="160"
/>
<el-table-column label="操作" width="160">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)"
>编辑</el-button
>
<el-button type="danger" link @click="handleDel(row)"
>删除</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
v-model="show"
:title="mode === 'add' ? '新增处理结果映射' : '编辑处理结果映射'"
width="600"
>
<el-form :label-width="140" :model="formData" ref="fomrRef">
<el-form-item
label="局长信箱处理结果"
prop="externalName"
:rules="{
required: true,
message: '请输入',
trigger: ['blur'],
}"
>
<el-input
v-model="formData.externalName"
clearable
style="width: 280px"
placeholder="请输入"
/>
</el-form-item>
<el-form-item
label="数字督察处理结果"
prop="internalId"
:rules="{
required: true,
message: '请输入',
trigger: ['blur'],
}"
>
<el-select
v-model="formData.internalId"
@change="(val) => {
formData.internalName = dict.handleResult
.find((obj) => val === obj.dictValue).dictLabel
}"
style="width: 280px"
clearable
>
<el-option
v-for="item in dict.handleResult"
:key="item.dictCode"
:value="item.dictValue"
:label="item.dictLabel"
/>
</el-select>
</el-form-item>
</el-form>
<footer class="flex end mt-40">
<el-button @click="show = false" size="large">取消</el-button>
<el-button type="primary" @click="submit" size="large"
>确定</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import {
listHandleResultMaping,
addHandleResultMaping,
updateHandleResultMaping,
delHandleResultMaping,
} from "@/api/system/handleResultMaping";
import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch";
const catchSotre = useCatchStore();
const dict = catchSotre.getDicts(["handleResult"]);
function getProblemType(id) {
console.log(dictContent);
dictContent.forEach(() => {
return "111";
});
for (let i = 0; i < dictContent.length; i++) {
const obj1 = dictContent[i];
if (obj1.id === id) {
return obj1.name;
}
if (!obj1.children) {
continue;
}
for (let j = 0; j < obj1.children.length; j++) {
const obj2 = obj1.children[j];
if (obj2.id === id) {
return obj1.name + " / " + obj2.name;
}
if (!obj2.children) {
continue;
}
for (let k = 0; k < obj2.children.length; k++) {
const obj3 = obj2.children[k];
if (obj3.id === id) {
return obj1.name + " / " + obj2.name + " / " + obj3.name;
}
}
}
}
}
const query = ref({
current: 1,
size: 10,
});
const list = ref([]);
const total = ref(0);
function getList() {
listHandleResultMaping(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
onMounted(() => {
getList();
});
const show = ref(false);
const mode = ref("add");
const formData = ref({});
const fomrRef = ref();
function handleAdd() {
formData.value = { internalId: "" };
show.value = true;
mode.value = "add";
}
function handleEdit(row) {
formData.value = { ...row };
show.value = true;
mode.value = "edit";
}
async function handleDel(row) {
await feedback.confirm("确定要删除该数据?");
await delHandleResultMaping(row.id);
getList();
feedback.msgSuccess("删除成功");
}
async function submit() {
await fomrRef.value.validate();
if (mode.value === "add") {
await addHandleResultMaping(formData.value);
} else {
await updateHandleResultMaping(formData.value);
}
show.value = false;
formData.value = {};
getList();
feedback.msgSuccess("操作成功");
}
</script>
<style lang="scss" scoped>
</style>

56
src/views/system/Menu.vue

@ -52,10 +52,7 @@
<el-button type="primary" link @click="handleEdit(row)" <el-button type="primary" link @click="handleEdit(row)"
>编辑</el-button >编辑</el-button
> >
<el-button <el-button type="danger" link @click="handleDelete(row)"
type="danger"
link
@click="handleDelete(row)"
>删除</el-button >删除</el-button
> >
</template> </template>
@ -128,7 +125,7 @@
v-if="formData.menuType === MenuEnum.CATALOGUE" v-if="formData.menuType === MenuEnum.CATALOGUE"
:rules="{ :rules="{
required: true, required: true,
message: '请选择图标' message: '请选择图标',
}" }"
prop="icon" prop="icon"
> >
@ -262,7 +259,9 @@
</el-form> </el-form>
<footer class="flex end"> <footer class="flex end">
<el-button @click="show = false">取消</el-button> <el-button @click="show = false">取消</el-button>
<el-button type="primary" @click="submit">确定</el-button> <el-button type="primary" @click="submit" :disabled="disabled"
>确定</el-button
>
</footer> </footer>
</el-dialog> </el-dialog>
</template> </template>
@ -310,7 +309,7 @@ const querySearch = (queryString, cb) => {
const mode = ref<string>("add"); const mode = ref<string>("add");
watch(mode, (val) => { watch(mode, (val) => {
if (val === "add") { if (val === "add") {
initFormData() initFormData();
} }
}); });
@ -323,33 +322,36 @@ function initFormData() {
} }
function handleAdd() { function handleAdd() {
show.value = true show.value = true;
mode.value = 'add' mode.value = "add";
} }
function submit() { const disabled = ref(false);
formRef.value.validate((flag) => { async function submit() {
if (flag) { await formRef.value.validate();
if (mode.value === "add") { disabled.value = true;
addMenu(formData.value).then(() => { try {
show.value = false; if (mode.value === "add") {
initFormData() await addMenu(formData.value);
getList(); initFormData();
}); } else {
} else { await updateMenu(formData.value);
updateMenu(formData.value).then(() => { }
show.value = false; } catch(e) {
getList(); console.error(e)
}); disabled.value = false;
} return
} }
}); disabled.value = false;
show.value = false;
getList();
feedback.msgSuccess('操作成功')
} }
function handleEdit(row) { function handleEdit(row) {
show.value = true; show.value = true;
mode.value = "edit"; mode.value = "edit";
formData.value = {...row}; formData.value = { ...row };
} }
const handleDelete = async (row) => { const handleDelete = async (row) => {

147
src/views/system/Police.vue

@ -256,35 +256,49 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="是否有账号" width="100" align="center">
<template #default="{ row }">
<span></span>
</template>
</el-table-column> -->
<el-table-column label="操作" width="220"> <el-table-column label="操作" width="220">
<template #default="{ row }"> <template #default="{ row }">
<el-button <div class="flex gap">
type="primary" <el-button
link type="primary"
@click="handleEdit(row)" link
v-perms="['police:add']" @click="handleEdit(row)"
>编辑</el-button v-perms="['police:add']"
> >编辑</el-button
<el-button >
type="primary"
link <div v-perms="['police:auth']">
@click="handleEditAuth(row)" <el-tooltip
v-perms="['police:auth']" effect="dark"
v-if="row.idCode" content="该警员身份证为空或无用户数据"
>权限设置</el-button placement="top"
> v-if="!row.idCode || !row.userId"
<el-button >
type="danger" <div>
link <el-button
@click="handleShowDel(row)" type="primary"
v-perms="['police:del']" link
>删除</el-button :disabled="true"
> >权限设置</el-button
>
</div>
</el-tooltip>
<el-button
type="primary"
link
@click="handleEditAuth(row)"
v-else
>权限设置</el-button
>
</div>
<el-button
type="danger"
link
@click="handleShowDel(row)"
v-perms="['police:del']"
>删除</el-button
>
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -303,6 +317,12 @@
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="异常警员"> <el-tab-pane label="异常警员">
<template #label>
<el-badge :value="abnormalTotal" v-if="abnormalTotal > 0">
<span class="tab-nav-title">异常警员</span>
</el-badge>
<span class="tab-nav-title" v-else>异常警员</span>
</template>
<header> <header>
<el-form :label-width="114"> <el-form :label-width="114">
<el-row> <el-row>
@ -381,7 +401,6 @@
</header> </header>
<div class="table-container" v-loading="loading"> <div class="table-container" v-loading="loading">
<el-table :data="abnormalPolices" row-key="id"> <el-table :data="abnormalPolices" row-key="id">
<el-table-column label="姓名" prop="name" width="90" /> <el-table-column label="姓名" prop="name" width="90" />
<el-table-column <el-table-column
label="警号" label="警号"
@ -439,7 +458,11 @@
prop="idCode" prop="idCode"
width="200" width="200"
/> />
<el-table-column label="异常原因" prop="delReason" show-overflow-tooltip /> <el-table-column
label="异常原因"
prop="delReason"
show-overflow-tooltip
/>
</el-table> </el-table>
</div> </div>
<div class="flex end mt-8"> <div class="flex end mt-8">
@ -465,6 +488,21 @@
:lock-scroll="false" :lock-scroll="false"
> >
<el-form :label-width="160"> <el-form :label-width="160">
<el-form-item label="用户角色">
<el-select
v-model="authForm.roleIds"
placeholder="请选择角色"
multiple
clearable
>
<el-option
v-for="item in roles"
:key="item.roleId"
:value="item.roleId"
:label="item.roleName"
/>
</el-select>
</el-form-item>
<el-form-item label="机构权限"> <el-form-item label="机构权限">
<depart-tree-select <depart-tree-select
v-model="authForm.departs" v-model="authForm.departs"
@ -640,6 +678,33 @@
> >
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="是否创建新用户" v-if="mode === 'add'">
<el-switch
v-model="form.createUserFlag"
inline-prompt
active-text="是"
inactive-text="否"
:active-value="true"
:inactive-value="false"
/>
</el-form-item>
<el-form-item
label="用戶密码"
v-if="mode === 'add' && form.createUserFlag"
:rules="{
required: true,
message: '请输入用户密码',
trigger: ['blur'],
}"
prop="password"
>
<el-input
type="password"
v-model="form.password"
placeholder="请输入用戶密码"
/>
<p class="text-small">用户密码默认为123456</p>
</el-form-item>
<!-- <el-form-item label="婚姻状况"> <!-- <el-form-item label="婚姻状况">
<el-radio-group v-model="form.maritalStatus"> <el-radio-group v-model="form.maritalStatus">
@ -696,7 +761,7 @@
prop="delReason" prop="delReason"
:rules="{ :rules="{
required: true, required: true,
message: '请输入姓名', message: '请输入其他原因',
}" }"
v-if="delFormData.option === `其他`" v-if="delFormData.option === `其他`"
> >
@ -710,7 +775,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<footer class="flex end"> <footer class="flex end">
<el-button @click="show = false">取消</el-button> <el-button @click="delDialog = false">取消</el-button>
<el-button type="primary" @click="handleDel">确定</el-button> <el-button type="primary" @click="handleDel">确定</el-button>
</footer> </footer>
</el-dialog> </el-dialog>
@ -783,9 +848,9 @@ function reset() {
const abnormalPolices = ref([]); const abnormalPolices = ref([]);
const abnormalQuery = ref({ const abnormalQuery = ref({
current: 1, current: 1,
size: 10, size: 10,
}) });
const abnormalTotal = ref(0) const abnormalTotal = ref(0);
function getAbnormalList() { function getAbnormalList() {
loading.value = true; loading.value = true;
listAbnormalPolice(abnormalQuery.value).then((data) => { listAbnormalPolice(abnormalQuery.value).then((data) => {
@ -803,7 +868,6 @@ function abnormalReset() {
getList(); getList();
} }
const authShow = ref(false); const authShow = ref(false);
const authForm = ref({}); const authForm = ref({});
let activeIdCode = ""; let activeIdCode = "";
@ -818,12 +882,15 @@ function handleEditAuth(row) {
function authSubmit() { function authSubmit() {
updatePoliceAuths(activeIdCode, authForm.value).then(() => { updatePoliceAuths(activeIdCode, authForm.value).then(() => {
authShow.value = false; authShow.value = false;
feedback.msgSuccess("操作成功"); feedback.msgSuccess("权限设置成功");
getList();
}); });
} }
const mode = ref("add"); const mode = ref("add");
const form = ref({}); const form = ref({
password: "123456",
});
const fomrRef = ref(null); const fomrRef = ref(null);
const show = ref(false); const show = ref(false);
@ -845,7 +912,9 @@ async function submit() {
await fomrRef.value.validate(); await fomrRef.value.validate();
if (mode.value === "add") { if (mode.value === "add") {
await addPolice(form.value); await addPolice(form.value);
form.value = {}; form.value = {
password: "123456",
};
} else { } else {
await updatePolice(form.value); await updatePolice(form.value);
} }
@ -925,7 +994,7 @@ async function handleDel(row) {
delDialog.value = false; delDialog.value = false;
delFormData.value = {}; delFormData.value = {};
getList(); getList();
getAbnormalList() getAbnormalList();
} }
function handleUploadImgSuccess(result, file) { function handleUploadImgSuccess(result, file) {

295
src/views/system/VideoConfig.vue

@ -0,0 +1,295 @@
<template>
<div class="container">
<header class="mb-20">
<el-form :label-width="114">
<el-row>
<el-col :span="6">
<el-form-item label="单位">
<el-tree-select
v-model="query.departId"
:data="departs"
:props="{ label: 'shortName', value: 'id' }"
node-key="id"
:default-expanded-keys="['12630']"
clearable
filterable
check-strictly
/>
</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="departName"
show-overflow-tooltip
/>
<el-table-column label="设备" prop="deviceName" />
<el-table-column
label="视频地址"
prop="videoUrl"
show-overflow-tooltip
/>
<el-table-column
label="排序"
prop="sortId"
width="90"
align="center"
/>
<el-table-column
label="创建时间"
prop="createTime"
width="180"
/>
<el-table-column label="操作" width="200">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleEdit(row)"
v-perms="['user:edit']"
>编辑</el-button
>
<el-button type="danger" link @click="handleDel(row)"
>删除</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="mode === 'add' ? '新增视频配置' : '编辑视频配置'"
v-model="show"
width="600"
>
<el-form :label-width="120" ref="formRef" :model="form">
<el-form-item
label="单位"
:rules="{
required: true,
message: '请选择',
trigger: ['blur'],
}"
prop="departId"
>
<el-tree-select
v-model="form.departId"
:data="departs"
:props="{ label: 'shortName', value: 'id' }"
node-key="id"
:default-expanded-keys="['12630']"
clearable
filterable
check-strictly
@node-click="handleDepartChange"
/>
</el-form-item>
<el-form-item
label="设备"
:rules="{
required: true,
message: '请选择',
trigger: ['blur'],
}"
prop="deviceId"
>
<el-tree-select
:data="devices"
v-model="form.deviceId"
:props="{
label: 'name',
value: 'deviceId',
disabled: nodeDisabled,
}"
node-key="id"
clearable
filterable
@current-change="handleDeviceChange"
>
<template #default="{ node, data }">
<div>
<span class="mr-10">{{ data.name }}</span>
<el-tag type="success" size="small" v-if="data.status === 'ON'">在线</el-tag>
<el-tag type="danger" size="small" v-if="data.status === 'OFF'">离线</el-tag>
</div>
</template>
</el-tree-select>
</el-form-item>
<el-form-item label="排序" prop="sortId">
<el-input
v-model="form.sortId"
type="number"
placeholder="排序"
/>
</el-form-item>
<el-form-item label="视频">
<div>
<div style="width: 400px">
<VideoPlay :url="form.videoUrl" />
</div>
<p style="height: 32px">{{ form.videoUrl }}</p>
</div>
</el-form-item>
</el-form>
<footer class="flex end">
<el-button @click="show = false" size="large">取消</el-button>
<el-button type="primary" @click="submit" size="large"
>确定</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import {
listVideoConfig,
listDevice,
addVideoConfig,
updateVideoConfig,
delVideoConfig,
getVideoWsUrl,
} from "@/api/system/videoConfig";
import { getCountyAndCityBureausTree } from "@/api/system/depart";
import feedback from "@/utils/feedback";
const list = ref([]);
const query = ref({
current: 1,
size: 10,
});
const total = ref(0);
function getList() {
listVideoConfig(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
});
}
function reset() {
query.value = {
current: 1,
size: 10,
};
getList();
}
const devices = ref([]);
const departs = ref([]);
let videoWsUrl = "";
onMounted(() => {
getList();
listDevice().then((data) => {
devices.value = data;
});
getCountyAndCityBureausTree().then((data) => {
departs.value = data;
});
getVideoWsUrl().then((data) => {
videoWsUrl = data;
});
});
const show = ref(false);
const mode = ref("add");
const form = ref({});
const formRef = ref(null);
function handleEdit(row) {
show.value = true;
mode.value = "edit";
form.value = row;
}
function handleDepartChange(node) {
form.value.departName = node.shortName;
}
function handleDeviceChange(node) {
if (departs.value.length > 0) {
form.value.parentId = devices.value[0].deviceId
}
form.value.deviceName = node.name;
}
watch(() => form.value.deviceId, () => {
form.value.videoUrl = `${videoWsUrl}rtp/${form.value.parentId}_${form.value.deviceId}.live.flv`;
})
function submit() {
formRef.value.validate((flag) => {
if (flag) {
if (mode.value === "edit") {
updateVideoConfig(form.value).then((data) => {
show.value = false;
form.value = {};
getList();
feedback.msgSuccess("操作成功");
});
} else {
addVideoConfig(form.value).then((data) => {
show.value = false;
form.value = {};
getList();
feedback.msgSuccess("操作成功");
});
}
}
});
}
watch(mode, (val) => {
if (val === "add") {
form.value = {};
}
});
function handleShowAdd() {
mode.value = "add";
show.value = true;
}
async function handleDel(row) {
await feedback.confirm("确定要删除该数据?");
await delVideoConfig(row.id);
getList();
}
function nodeDisabled(data) {
return data.status === "OFF";
}
</script>
<style lang="scss" scoped>
</style>

1
src/views/system/Wqzg.vue

@ -54,6 +54,7 @@
</el-table-column> </el-table-column>
<el-table-column label="警员姓名" prop="empName" width="200" /> <el-table-column label="警员姓名" prop="empName" width="200" />
<el-table-column label="警号" prop="empNo" width="200" /> <el-table-column label="警号" prop="empNo" width="200" />
<el-table-column label="身份证" prop="idCode" width="200" />
<el-table-column <el-table-column
label="市局维权专干" label="市局维权专干"
align="center" align="center"

29
src/views/work/Alarm.vue

@ -97,7 +97,11 @@
width="100" width="100"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column label="提醒内容" prop="alarmContent" show-overflow-tooltip /> <el-table-column
label="提醒内容"
prop="alarmContent"
show-overflow-tooltip
/>
<el-table-column label="回复情况" width="110"> <el-table-column label="回复情况" width="110">
<template #default="{ row }"> <template #default="{ row }">
<el-text v-if="row.replyState == 1" class="mx-1" <el-text v-if="row.replyState == 1" class="mx-1"
@ -134,7 +138,6 @@
</div> </div>
</main> </main>
<el-dialog title="查看详情" v-model="dialogShow" width="800"> <el-dialog title="查看详情" v-model="dialogShow" width="800">
<el-form :model="showData" :label-width="120" ref="fomrRef"> <el-form :model="showData" :label-width="120" ref="fomrRef">
<el-row> <el-row>
@ -179,11 +182,11 @@
</el-row> </el-row>
<el-row <el-row
style="margin-top: 10px" style="margin-top: 10px"
v-if="showData.files != undefined && showData.files.length > 0" v-if="
showData.files != undefined && showData.files.length > 0
"
> >
<el-form-item label="问题附件"> <el-form-item label="问题附件"> </el-form-item>
</el-form-item>
</el-row> </el-row>
</el-form> </el-form>
<footer class="flex end"> <footer class="flex end">
@ -191,16 +194,12 @@
</footer> </footer>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import moment from "moment"; import moment from "moment";
import { Clock } from "@element-plus/icons-vue"; import { Clock } from "@element-plus/icons-vue";
import { import { alarmNotificationPages, alarmFiles } from "@/api/work/alarm";
alarmNotificationPages,
alarmFiles,
} from "@/api/work/alarm";
import feedback from "@/utils/feedback"; import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
@ -322,7 +321,6 @@ function handleAction(row) {
} }
const router = useRouter(); const router = useRouter();
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.form-row { .form-row {
@ -351,6 +349,11 @@ const router = useRouter();
} }
.query-box { .query-box {
gap: 10px 20px; > * {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
}
} }
</style> </style>

26
src/views/work/BatchDistribute.vue

@ -83,7 +83,8 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<div class="flex end mt-8"> <div class="flex between v-center mt-8">
<div>说明批量下发列表展示问题导入标准模板及其他来源问题导入模板下发的任务情况</div>
<el-pagination <el-pagination
@size-change="getList" @size-change="getList"
@current-change="getList" @current-change="getList"
@ -146,6 +147,7 @@
>问题批量导入标准模板.xlsx 下载</a >问题批量导入标准模板.xlsx 下载</a
> >
</div> </div>
<div class="mt-10">说明请上传问题批量导入标准模板上传成功后点击下一步进行数据校验</div>
</template> </template>
<template v-if="activeStep === 1"> <template v-if="activeStep === 1">
<div class="table-container"> <div class="table-container">
@ -383,7 +385,7 @@
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { listNegativeTaskImport, importNegative, distributeNegative, listGroupByDepart } from "@/api/work/negativeTask"; import { listNegativeTask, importNegative, distributeNegative, listGroupByDepart } from "@/api/work/negativeTask";
import feedback from "@/utils/feedback"; import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
import { BASE_PATH } from "@/api/request"; import { BASE_PATH } from "@/api/request";
@ -392,22 +394,34 @@ const catchStore = useCatchStore();
const dict = catchStore.getDicts([ const dict = catchStore.getDicts([
"approvalFlow", "approvalFlow",
"distributionFlow", "distributionFlow",
"businessType", "businessType"
]); ]);
const router = useRouter() const router = useRouter()
const query = ref({}); const query = ref({
size: 10,
current: 1,
category: '0'
});
const list = ref([]); const list = ref([]);
const total = ref(0); const total = ref(0);
function getList() { function getList() {
listNegativeTaskImport(query.value).then((data) => { listNegativeTask(query.value).then((data) => {
list.value = data.records; list.value = data.records;
total.value = data.total; total.value = data.total;
}); });
} }
function reset() {
query.value = {
size: 10,
current: 1,
category: '0'
};
getList();
}
onMounted(() => { onMounted(() => {
getList(); getList();
}); });

3
src/views/work/Done.vue

@ -370,7 +370,8 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<div class="flex end mt-8"> <div class="flex between v-center mt-8">
<div>说明已办列表展示当前与本人处理过但尚未办结的工作</div>
<el-pagination <el-pagination
@size-change="getList" @size-change="getList"
@current-change="getList" @current-change="getList"

528
src/views/work/MyCountersign.vue

@ -0,0 +1,528 @@
<template>
<div class="container">
<header>
<el-form :label-width="120">
<el-row>
<el-col :span="6">
<el-form-item label="问题发现时间">
<date-time-range-picker-ext
v-model="query.discoveryTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="问题发生时间">
<date-time-range-picker-ext
v-model="query.happenTime"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="问题录入时间">
<date-time-range-picker-ext
v-model="query.crtTime"
/>
</el-form-item>
</el-col>
</el-row>
<div class="form-row flex">
<label class="text-center">问题信息</label>
<div class="flex wrap query-box">
<el-input
placeholder="问题编号 / 样本源头编号"
v-model="query.originId"
clearable
style="width: 200px"
/>
<el-input
placeholder="涉及案件 / 警情编号"
v-model="query.caseNumber"
clearable
style="width: 200px"
/>
<el-input
placeholder="事情简要描述"
v-model="query.thingDesc"
clearable
style="width: 260px"
/>
<el-select
style="width: 146px"
placeholder="业务类别"
clearable
v-model="query.businessTypeCode"
>
<el-option
v-for="item in dict.businessType"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<el-tree-select
:data="dictProblemSources"
:props="{ value: 'id' }"
node-key="id"
v-model="query.problemSourcesCode"
clearable
filterable
multiple
collapse-tags
style="width: 200px"
placeholder="问题来源"
/>
<el-select
style="width: 146px"
placeholder="专项督察"
clearable
v-model="query.specialSupervision"
>
<el-option
v-for="item in dict.specialSupervision"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<el-input
placeholder="通报期数"
style="width: 146px"
v-model="query.reportNumber"
clearable
/>
</div>
</div>
<div class="form-row flex">
<label class="text-center">核查情况</label>
<div class="flex wrap query-box">
<div style="width: 200px">
<depart-tree-select
v-model="query.involveDepartId"
placeholder="涉及单位"
/>
</div>
<div style="width: 200px">
<depart-tree-select
v-model="query.handleDepartId"
placeholder="办理单位"
/>
</div>
<el-select
style="width: 120px"
placeholder="是否属实"
clearable
v-model="query.checkStatus"
>
<el-option
v-for="item in dict.inspectCase"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="是否整改"
clearable
v-model="query.isRectifyCode"
>
<el-option
v-for="item in dict.isRectify"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<div class="flex gap-4">
<el-select
v-model="query.blameKey"
style="width: 90px"
@change="delete query.blameValue"
>
<el-option value="name" label="姓名" />
<el-option value="empNo" label="警号" />
<el-option value="idCode" label="身份证" />
</el-select>
<el-input
placeholder="涉及人员"
v-model="query.blameValue"
clearable
style="width: 190px"
/>
</div>
</div>
</div>
<div class="form-row flex">
<label class="text-center">其他选项</label>
<div class="flex wrap query-box">
<el-select
style="width: 200px"
placeholder="流程阶段"
clearable
v-model="query.flowKey"
>
<el-option
v-for="item in flowNodes"
:key="item.flowKey"
:label="item.flowName"
:value="item.flowKey"
/>
</el-select>
<el-select
style="width: 120px"
placeholder="办理状态"
clearable
v-model="query.processingStatus"
multiple
>
<el-option
v-for="item in dict.processingStatus"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
<div class="flex gap-4" style="height: 32px">
<el-select
v-model="query.responderKey"
style="width: 90px"
@change="delete query.responderValue"
>
<el-option value="name" label="姓名" />
<el-option value="phone" label="电话" />
</el-select>
<el-input
placeholder="投诉反映人"
v-model="query.responderValue"
clearable
style="width: 190px"
/>
</div>
<el-select
style="width: 120px"
placeholder="申请延期"
clearable
v-model="query.extensionFlag"
>
<el-option label="已申请" :value="true" />
<el-option label="未申请" :value="false" />
</el-select>
<el-select
style="width: 146px"
placeholder="下发单位的层级"
clearable
v-model="query.crtDepartLevel"
>
<el-option label="市局下发" :value="0" />
<el-option label="二级机构下发" :value="2" />
</el-select>
</div>
</div>
</el-form>
<div class="flex between mt-20 mb-26">
<el-button type="primary" @click="handleExport"
>数据导出</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>
<main>
<div class="table-container" v-loading="loading">
<el-table
:data="list"
@sort-change="handleTableSort"
ref="tableRef"
>
<el-table-column type="expand">
<template #default="{ row }">
<div class="row mt-10">
<div class="col col-6">
<label>样本源头编号</label>
<span>{{ row.originId }}</span>
</div>
<div class="col col-6">
<label>问题发现时间</label>
<span>{{ row.discoveryTime }}</span>
</div>
<div class="col col-6">
<label>问题发生时间</label>
<span>{{ row.happenTime || "/" }}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-6">
<label>问题来源</label>
<span>{{ row.problemSources }}</span>
</div>
<div class="col col-6">
<label>业务类别</label>
<span>{{ row.businessTypeName }}</span>
</div>
<div class="col col-12">
<label>涉嫌问题</label>
<span>{{
getInvolveProblem(
row.involveProblem,
dict.suspectProblem
) || "/"
}}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-6" v-if="row.responderName">
<label>投诉反映人</label>
<span>{{ row.responderName }}</span>
</div>
<div class="col col-6" v-if="row.contactPhone">
<label>联系电话</label>
<span>{{ row.contactPhone }}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-6">
<label>涉及警种</label>
<span>{{ row.policeTypeName }}</span>
</div>
<div class="col col-6">
<label>涉及单位</label>
<span>{{
row.involveDepartName || "/"
}}</span>
</div>
</div>
<div class="row mt-10">
<div class="col col-24">
<label>事情简要描述</label>
<span>{{ row.thingDesc }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column
label="问题录入时间"
prop="crtTime"
width="150"
sortable="custom"
/>
<el-table-column
label="问题发现时间"
prop="discoveryTime"
width="150"
sortable="custom"
/>
<el-table-column
label="问题来源"
prop="problemSources"
width="110"
/>
<el-table-column
label="业务类别"
prop="businessTypeName"
width="110"
/>
<el-table-column
label="问题内容"
prop="thingDesc"
show-overflow-tooltip
/>
<el-table-column label="办理单位" show-overflow-tooltip>
<template #default="{ row }">
<span
>{{ row.handleSecondDepartName
}}{{ row.handleThreeDepartName }}</span
>
</template>
</el-table-column>
<el-table-column
label="是否属实"
prop="checkStatusName"
width="100"
align="center"
/>
<el-table-column label="办理状态" width="110">
<template #default="{ row }">
<el-tag
:type="
row.processingStatus ===
ProcessingStatus.COMPLETED
? 'success'
: 'primary'
"
v-if="row.processingStatus"
>{{
getDictLable(
dict.processingStatus,
row.processingStatus
)
}}</el-tag
>
</template>
</el-table-column>
<el-table-column
label="当前处理对象"
prop="currentProcessingObject"
show-overflow-tooltip
>
<template #default="{ row }">
<span
v-if="
row.processingStatus ===
ProcessingStatus.COMPLETED
"
></span
>
<span v-else>{{
row.currentProcessingObject
}}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleAction(row)"
>详情</el-button
>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex between v-center mt-8">
<div>说明会签列表展示拥有同样权限的专班成员会签过的工作</div>
<el-pagination
@size-change="getList"
@current-change="getList"
:page-sizes="[10, 20, 50, 100]"
v-model:page-size="query.size"
v-model:current-page="query.current"
layout="total, sizes, prev, pager, next"
:total="total"
>
</el-pagination>
</div>
</main>
</div>
<negative-dialog
v-model="show"
:id="activeNegativeId"
@close="show = false"
ref="negativeDialogRef"
/>
</template>
<script setup>
import moment from "moment";
import { ElLoading } from "element-plus";
import {
listMyCountersign,
negativeExport
} from "@/api/work/myCountersign";
import { getDictLable, getInvolveProblem } from "@/utils/util";
import feedback from "@/utils/feedback";
import { ProcessingStatus } from "@/enums/flowEnums";
import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore();
const dict = catchStore.getDicts([
"businessType",
"inspectCase",
"isRectify",
"processingStatus",
"suspectProblem",
"policeType",
"specialSupervision",
]);
const flowNodes = catchStore.getFlowNodes();
const dictProblemSources = catchStore.getDictProblemSources();
const queryCrumbs = ref([]);
const query = ref({
current: 1,
size: 10,
responderKey: "name",
blameKey: "name"
});
const list = ref([]);
const total = ref(0);
const loading = ref(true);
function getList() {
loading.value = true;
listMyCountersign(query.value).then((data) => {
list.value = data.records;
total.value = data.total;
loading.value = false;
});
}
function handleTableSort(orderObj) {
if (orderObj.order) {
query.value.order = orderObj.order;
query.value.orderProp = orderObj.prop;
} else {
query.value.order = "";
query.value.orderProp = "";
}
getList();
}
const tableRef = ref();
function reset() {
query.value = {
current: 1,
size: 10,
responderKey: "name",
blameKey: "name"
};
tableRef.value.clearSort();
getList();
}
onMounted(() => {
getList();
});
const show = ref(false);
const activeNegativeId = ref("");
function handleAction(row) {
show.value = true;
activeNegativeId.value = row.id;
}
const router = useRouter();
async function handleExport() {
await feedback.confirm("请确定导出当前页面所有数据");
const loading = ElLoading.service({
lock: true,
text: "导出中...",
background: "rgba(0, 0, 0, 0.5)",
});
await negativeExport(query.value);
loading.close();
await feedback.confirm("导出任务已生成,请到“导出记录”页面查看");
router.push("/negative/export");
}
</script>
<style lang="scss" scoped>
</style>

14
src/views/work/NegativeImport.vue

@ -1,11 +1,12 @@
<template> <template>
<div class="container"> <div class="container">
<header> <header>
<div class="flex gap"> <div class="flex gap">
<el-upload <el-upload
:multiple="false" :multiple="false"
:show-file-list="false" :show-file-list="false"
:action="`${BASE_PATH}/negative/import`" :action="`${BASE_PATH}/negative/import/sj`"
:headers="{ Authorization: getToken() }" :headers="{ Authorization: getToken() }"
:before-upload="beforeUpload" :before-upload="beforeUpload"
@success="handleSuccess" @success="handleSuccess"
@ -16,18 +17,9 @@
<el-button type="primary"> <el-button type="primary">
<template #icon> <template #icon>
<icon name="el-icon-Upload" /> <icon name="el-icon-Upload" />
</template> </template>审计问题</el-button
黄赌毒历史问题下发</el-button
> >
</el-upload> </el-upload>
<a
class="link"
:href="`${BASE_PATH}/templates/黄赌问题问题下发模板.xls`"
target="__blank"
style="padding: 8px"
v-perms="['police:import']"
>黄赌毒历史问题模板下载</a
>
</div> </div>
</header> </header>
</div> </div>

6
src/views/work/NegativeTask.vue

@ -56,6 +56,7 @@
type="primary" type="primary"
link link
@click="handleDownload(row)" @click="handleDownload(row)"
:disabled="row.status !== '0'"
>下载</el-button >下载</el-button
> >
</template> </template>
@ -84,6 +85,7 @@ const list = ref([]);
const query = ref({ const query = ref({
size: 10, size: 10,
current: 1, current: 1,
category: '2'
}); });
const total = ref(0); const total = ref(0);
@ -98,6 +100,7 @@ function reset() {
query.value = { query.value = {
size: 10, size: 10,
current: 1, current: 1,
category: '2'
}; };
getList(); getList();
} }
@ -107,6 +110,9 @@ onMounted(() => {
}); });
function handleDownload(row) { function handleDownload(row) {
if (row.status !== '1') {
}
fetch(`${BASE_PATH}/file/stream${row.filePath}`) fetch(`${BASE_PATH}/file/stream${row.filePath}`)
.then((response) => { .then((response) => {
console.log(response); console.log(response);

185
src/views/work/News.vue

@ -75,6 +75,9 @@
<el-table-column label="动态内容" prop="contentTxt" /> <el-table-column label="动态内容" prop="contentTxt" />
<el-table-column label="操作" width="160"> <el-table-column label="操作" width="160">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" link @click="handleShow(row)"
>查看</el-button
>
<el-button type="primary" link @click="handleEdit(row)" <el-button type="primary" link @click="handleEdit(row)"
>编辑</el-button >编辑</el-button
> >
@ -110,65 +113,18 @@
ref="fomrRef" ref="fomrRef"
style="min-height: 40vh" style="min-height: 40vh"
> >
<el-row>
<el-col :span="12">
<el-form-item
label="动态类型"
prop="source"
:rules="{
required: true,
message: '请选择',
trigger: ['blur'],
}"
>
<el-radio-group v-model="formData.source">
<el-radio
v-for="item in dict.newsWorkSource"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="发布时间"
prop="releaseTime"
:rules="{
required: true,
message: '请选择',
trigger: ['blur'],
}"
>
<el-date-picker
v-model="formData.releaseTime"
type="datetime"
placeholder="请选择"
value-format="YYYY-MM-DD HH:mm"
time-format="HH:mm"
style="width: 100%"
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item <el-form-item
label="动态类" label="动态类型"
prop="workType" prop="source"
:rules="{ :rules="{
required: true, required: true,
message: '请选择', message: '请选择',
trigger: ['blur'], trigger: ['blur'],
}" }"
> >
<el-radio-group v-model="formData.workType"> <el-radio-group v-model="formData.source">
<el-radio <el-radio
v-for="item in dict.newsWorkType" v-for="item in dict.newsWorkSource"
:key="item.dictCode" :key="item.dictCode"
:value="item.dictValue" :value="item.dictValue"
>{{ item.dictLabel >{{ item.dictLabel
@ -176,6 +132,41 @@
> >
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item
label="动态分类"
prop="workType"
:rules="{
required: true,
message: '请选择',
trigger: ['blur'],
}"
>
<el-radio-group v-model="formData.workType">
<template v-if="formData.source !== '审计工作动态'">
<el-radio
v-for="item in dict.newsWorkType"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</template>
<template v-else>
<el-radio
v-for="item in dict.newsSjWorkType"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</template>
</el-radio-group>
</el-form-item>
<el-form-item <el-form-item
label="发布单位" label="发布单位"
prop="departId" prop="departId"
@ -186,9 +177,32 @@
}" }"
> >
<div style="width: 300px"> <div style="width: 300px">
<depart-tree-select v-model="formData.departId" @node-click="(node) => formData.departName = node.shortName" /> <depart-tree-select
v-model="formData.departId"
@node-click="
(node) => (formData.departName = node.shortName)
"
/>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item
label="发布时间"
prop="releaseTime"
:rules="{
required: true,
message: '请选择',
trigger: ['blur'],
}"
>
<el-date-picker
v-model="formData.releaseTime"
type="datetime"
placeholder="请选择"
value-format="YYYY-MM-DD HH:mm"
time-format="HH:mm"
style="width: 300px"
/>
</el-form-item>
<el-form-item <el-form-item
label="动态内容" label="动态内容"
prop="contentTxt" prop="contentTxt"
@ -206,6 +220,9 @@
:autosize="{ minRows: 6, maxRows: 10 }" :autosize="{ minRows: 6, maxRows: 10 }"
/> />
</el-form-item> </el-form-item>
<el-form-item label="附件">
<file-upload v-model:files="formData.files" accept="image/*" />
</el-form-item>
</el-form> </el-form>
<footer class="flex end mt-40"> <footer class="flex end mt-40">
<el-button @click="show = false" size="large">取消</el-button> <el-button @click="show = false" size="large">取消</el-button>
@ -214,14 +231,54 @@
> >
</footer> </footer>
</el-dialog> </el-dialog>
<el-dialog v-model="detailShow" title="工作动态详情" width="60vw">
<div style="padding: 20px 40px; min-height: 50vh">
<div class="row">
<div class="col col-12">
<label>动态类型</label>
<span>{{ activeRow.source }}</span>
</div>
<div class="col col-12">
<label>动态分类</label>
<span>{{ activeRow.workType }}</span>
</div>
<div class="col col-12">
<label>发布单位</label>
<span>{{ activeRow.departName }}</span>
</div>
<div class="col col-12">
<label>发布时间</label>
<span>{{ activeRow.releaseTime }}</span>
</div>
</div>
<div>
<div class="text-primary mt-10">内容</div>
<div class="content mb-20">{{ activeRow.contentTxt }}</div>
</div>
<div>
<div class="text-primary mt-10 mb-10">附件</div>
<file-list
:files="activeRow.files"
v-if="activeRow.files.length > 0"
/>
<el-empty v-else description="无附件" style="--el-empty-image-width: 50px" />
</div>
</div>
</el-dialog>
</template> </template>
<script setup> <script setup>
import moment from "moment";
import { listNews, addNews, updateNews, delNews } from "@/api/work/news"; import { listNews, addNews, updateNews, delNews } from "@/api/work/news";
import feedback from "@/utils/feedback"; import feedback from "@/utils/feedback";
import useCatchStore from "@/stores/modules/catch"; import useCatchStore from "@/stores/modules/catch";
const catchStore = useCatchStore(); const catchStore = useCatchStore();
const dict = catchStore.getDicts(["newsWorkType", "newsWorkSource"]); const dict = catchStore.getDicts([
"newsWorkType",
"newsSjWorkType",
"newsWorkSource",
]);
const query = ref({ const query = ref({
current: 1, current: 1,
@ -255,12 +312,20 @@ const formData = ref({});
const fomrRef = ref(); const fomrRef = ref();
function handleAdd() { function handleAdd() {
formData.value = { internalId: "" }; formData.value = {
internalId: "",
releaseTime: moment().format("YYYY-MM-DD HH:mm"),
};
show.value = true; show.value = true;
mode.value = "add"; mode.value = "add";
} }
function handleEdit(row) { function handleEdit(row) {
formData.value = { ...row }; formData.value = { ...row };
if (formData.value.files) {
formData.value.files = JSON.parse(formData.value.files);
} else {
formData.value.files = [];
}
show.value = true; show.value = true;
mode.value = "edit"; mode.value = "edit";
} }
@ -284,6 +349,18 @@ async function submit() {
getList(); getList();
feedback.msgSuccess("操作成功"); feedback.msgSuccess("操作成功");
} }
const detailShow = ref(false);
const activeRow = ref({});
function handleShow(row) {
activeRow.value = { ...row };
if (activeRow.value.files) {
activeRow.value.files = JSON.parse(activeRow.value.files);
} else {
activeRow.value.files = [];
}
detailShow.value = true;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
</style> </style>

154
src/views/work/Query.vue

@ -90,7 +90,6 @@
v-model="query.reportNumber" v-model="query.reportNumber"
clearable clearable
/> />
</div> </div>
</div> </div>
<div class="form-row flex"> <div class="form-row flex">
@ -204,7 +203,6 @@
<el-option label="办结超时" :value="true" /> <el-option label="办结超时" :value="true" />
</el-select> </el-select>
<div class="flex gap-4" style="height: 32px"> <div class="flex gap-4" style="height: 32px">
<el-select <el-select
v-model="query.responderKey" v-model="query.responderKey"
@ -239,8 +237,6 @@
<el-option label="市局下发" :value="0" /> <el-option label="市局下发" :value="0" />
<el-option label="二级机构下发" :value="2" /> <el-option label="二级机构下发" :value="2" />
</el-select> </el-select>
</div> </div>
</div> </div>
</el-form> </el-form>
@ -249,6 +245,15 @@
>数据导出</el-button >数据导出</el-button
> >
<div> <div>
<el-switch
v-model="remainingTimeFlag"
inline-prompt
active-text="显示流程限时"
inactive-text="隐藏流程限时"
:active-value="true"
:inactive-value="false"
class="mr-20"
/>
<el-button type="primary" @click="getList"> <el-button type="primary" @click="getList">
<template #icon <template #icon
><icon name="el-icon-Search" ><icon name="el-icon-Search"
@ -348,6 +353,7 @@
label="问题来源" label="问题来源"
prop="problemSources" prop="problemSources"
width="110" width="110"
show-overflow-tooltip
/> />
<el-table-column <el-table-column
label="业务类别" label="业务类别"
@ -378,6 +384,7 @@
label="流程限时" label="流程限时"
width="150" width="150"
align="center" align="center"
v-if="remainingTimeFlag"
> >
<template #default="{ row }"> <template #default="{ row }">
<countdown <countdown
@ -434,49 +441,79 @@
}}</span> }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="220"> <el-table-column label="操作" width="160">
<template #default="{ row }"> <template #default="{ row }">
<el-button <div class="flex v-center">
type="primary" <el-button
link type="primary"
@click="handleAction(row)" link
>详情</el-button @click="handleAction(row)"
> >详情</el-button
<el-button >
type="primary" <el-dropdown
link trigger="click"
@click="handleEdit(row)" placement="bottom-start"
v-perms="['negative:edit']" class="ml-10"
>编辑</el-button >
> <el-button type="primary" link
<el-button >更多操作</el-button
type="danger" >
link <template #dropdown>
@click="handleDel(row)" <el-dropdown-menu>
v-perms="['negative:del']" <el-dropdown-item>
>删除</el-button <el-button
> type="primary"
<el-button text
type="primary" @click="handleEdit(row)"
link v-perms="['negative:edit']"
@click="handleTransferTodo(row)" >编辑</el-button
v-perms="['negative:transferTodo']" >
v-if=" </el-dropdown-item>
row.processingStatus === <el-dropdown-item>
ProcessingStatus.COMPLETED <el-button
" type="danger"
>转待办</el-button text
> @click="handleDel(row)"
<el-button v-perms="['negative:del']"
type="primary" >删除</el-button
link >
v-if=" </el-dropdown-item>
row.processingStatus === <el-dropdown-item>
ProcessingStatus.COMPLETED <el-button
" type="primary"
@click="handleSpotCheck(row)" text
>抽查</el-button @click="
> handleTransferTodo(row)
"
v-perms="[
'negative:transferTodo',
]"
v-if="
row.processingStatus ===
ProcessingStatus.COMPLETED
"
>转待办</el-button
>
</el-dropdown-item>
<el-dropdown-item>
<el-button
type="primary"
text
v-if="
row.processingStatus ===
ProcessingStatus.COMPLETED
"
@click="
handleSpotCheck(row)
"
v-perms="['negative:spotCheck']"
>抽查</el-button
>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -778,6 +815,7 @@
> >
</footer> </footer>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import moment from "moment"; import moment from "moment";
@ -805,7 +843,7 @@ const dict = catchStore.getDicts([
"processingStatus", "processingStatus",
"suspectProblem", "suspectProblem",
"policeType", "policeType",
"specialSupervision", "specialSupervision"
]); ]);
const flowNodes = catchStore.getFlowNodes(); const flowNodes = catchStore.getFlowNodes();
const dictProblemSources = catchStore.getDictProblemSources(); const dictProblemSources = catchStore.getDictProblemSources();
@ -815,7 +853,7 @@ const query = ref({
current: 1, current: 1,
size: 10, size: 10,
responderKey: "name", responderKey: "name",
blameKey: "name" blameKey: "name",
}); });
const list = ref([]); const list = ref([]);
@ -848,7 +886,7 @@ function reset() {
current: 1, current: 1,
size: 10, size: 10,
responderKey: "name", responderKey: "name",
blameKey: "name" blameKey: "name",
}; };
tableRef.value.clearSort(); tableRef.value.clearSort();
getList(); getList();
@ -858,7 +896,7 @@ function reset() {
const route = useRoute(); const route = useRoute();
watch( watch(
() => route.query, () => route.query.toString(),
() => { () => {
updateQuery(); updateQuery();
getList(); getList();
@ -868,21 +906,15 @@ watch(
function updateQuery() { function updateQuery() {
if (route.query.processingStatus) { if (route.query.processingStatus) {
query.value.processingStatus = [route.query.processingStatus]; query.value.processingStatus = [route.query.processingStatus];
} else {
query.value.processingStatus = [];
} }
if (route.query.crtTime === "today") { if (route.query.crtTime === "today") {
query.value.crtTime = [ query.value.crtTime = [
moment().startOf("day").format("YYYY-MM-DD HH:mm:ss"), moment().startOf("day").format("YYYY-MM-DD HH:mm:ss"),
moment().endOf("day").format("YYYY-MM-DD HH:mm:ss"), moment().endOf("day").format("YYYY-MM-DD HH:mm:ss"),
]; ];
} else {
query.value.crtTime = [];
} }
if (route.query.extensionFlag === "true") { if (route.query.extensionFlag === "true") {
query.value.extensionFlag = true; query.value.extensionFlag = true;
} else {
query.value.extensionFlag = "";
} }
} }
@ -957,6 +989,16 @@ function handleSpotCheck(row) {
show.value = true; show.value = true;
negativeDialogRef.value.spotCheck(); negativeDialogRef.value.spotCheck();
} }
const remainingTimeFlag = ref(true);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep() {
.el-dropdown-menu__item {
padding: 0;
.el-button {
width: 100%;
}
}
}
</style> </style>

72
src/views/work/Todo.vue

@ -90,7 +90,6 @@
v-model="query.reportNumber" v-model="query.reportNumber"
clearable clearable
/> />
</div> </div>
</div> </div>
<div class="form-row flex"> <div class="form-row flex">
@ -151,10 +150,13 @@
style="width: 190px" style="width: 190px"
/> />
</div> </div>
<el-select placeholder="处置结果" <el-select
v-model="query.handleResultCode" placeholder="处置结果"
clearable v-model="query.handleResultCode"
style="width: 280px" multiple> clearable
style="width: 280px"
multiple
>
<el-option <el-option
v-for="item in dict.handleResult" v-for="item in dict.handleResult"
:key="item.id" :key="item.id"
@ -242,14 +244,26 @@
</div> </div>
</el-form> </el-form>
<div class="flex between mt-20 mb-26"> <div class="flex between mt-20 mb-26">
<el-button
type="primary"
@click="addShow = true"
v-perms="['negative:add']"
><template #icon> <icon name="el-icon-Plus" /> </template
>问题下发</el-button
>
<div> <div>
<el-button
type="primary"
@click="addShow = true"
v-perms="['negative:add']"
><template #icon>
<icon name="el-icon-Plus" /> </template
>问题下发</el-button
>
</div>
<div>
<el-switch
v-model="remainingTimeFlag"
inline-prompt
active-text="显示流程限时"
inactive-text="隐藏流程限时"
:active-value="true"
:inactive-value="false"
class="mr-20"
/>
<el-button type="primary" @click="getList"> <el-button type="primary" @click="getList">
<template #icon <template #icon
><icon name="el-icon-Search" ><icon name="el-icon-Search"
@ -300,7 +314,10 @@
<div class="col col-6"> <div class="col col-6">
<label>涉嫌问题</label> <label>涉嫌问题</label>
<span>{{ <span>{{
getInvolveProblem(row.involveProblem, dict.suspectProblem) getInvolveProblem(
row.involveProblem,
dict.suspectProblem
)
}}</span> }}</span>
</div> </div>
</div> </div>
@ -325,7 +342,12 @@
<el-table-column label="业务类别" prop="businessTypeName" /> <el-table-column label="业务类别" prop="businessTypeName" />
<el-table-column label="涉嫌问题"> <el-table-column label="涉嫌问题">
<template #default="{ row }"> <template #default="{ row }">
<span>{{ getInvolveProblem(row.involveProblem, dict.suspectProblem) }}</span> <span>{{
getInvolveProblem(
row.involveProblem,
dict.suspectProblem
)
}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
@ -360,15 +382,21 @@
dict.processingStatus, dict.processingStatus,
row.processingStatus row.processingStatus
) )
}}{{ row.extensionApplyFlag ? "" : "(延期申请)"
}}{{ }}{{
row.extensionApplyFlag ? "" : "(延期申请)" row.workFlowKey === "countersign"
}}{{ ? "(单位会签)"
row.workFlowKey === 'countersign' ? "(单位会签)" : "" : ""
}}</el-tag }}</el-tag
> >
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="流程限时" width="150" align="center"> <el-table-column
label="流程限时"
width="150"
align="center"
v-if="remainingTimeFlag"
>
<template #default="{ row }"> <template #default="{ row }">
<countdown <countdown
:time="row.remainingDuration" :time="row.remainingDuration"
@ -408,7 +436,8 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<div class="flex end mt-8"> <div class="flex between v-center mt-8">
<div>说明待办列表展示当前需要本人待办的工作已办结/已审批问题请前往 <span class="link pointer" @click="router.push('/query')">综合查询</span>列表查看</div>
<el-pagination <el-pagination
@size-change="getList" @size-change="getList"
@current-change="getList" @current-change="getList"
@ -420,6 +449,7 @@
> >
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
<negative-dialog <negative-dialog
@ -445,7 +475,9 @@ const dict = catchStore.getDicts([
"processingStatus", "processingStatus",
"inspectCase", "inspectCase",
"handleResult", "handleResult",
"isRectify"
]); ]);
const router = useRouter()
const flowNodes = catchStore.getFlowNodes(); const flowNodes = catchStore.getFlowNodes();
const dictProblemSources = catchStore.getDictProblemSources(); const dictProblemSources = catchStore.getDictProblemSources();
@ -490,6 +522,8 @@ function handleAction(row) {
} }
const addShow = ref(false); const addShow = ref(false);
const remainingTimeFlag = ref(true);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
</style> </style>

1813
src/views/work/VerifySubmit.vue

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save