Compare commits

...

83 Commits

Author SHA1 Message Date
c67b63b4f1 更新 2026-03-06 16:02:10 +08:00
4518038d9e 更新 2026-03-06 16:01:08 +08:00
78c828763b 更新 2026-03-06 15:03:42 +08:00
dcf680163a 更新 2026-03-06 15:02:51 +08:00
b1ea8f2e5b 更新 2026-03-06 14:45:30 +08:00
e561ef9e6d 解决冲突 2026-02-24 09:18:32 +08:00
b8c393f773 更新 2026-02-24 09:16:07 +08:00
lcw
f30a2d7411 lcw 2026-02-07 16:54:04 +08:00
lcw
d2e4fc137d Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-02-07 10:24:37 +08:00
lcw
c0ba4c7c49 lcw 2026-02-07 10:24:29 +08:00
2aef20eabf Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-02-06 15:01:01 +08:00
9d4aba2f47 更新情报采集 2026-02-06 15:00:13 +08:00
lcw
323fcd25fe lcw 2026-02-05 17:17:25 +08:00
lcw
872fcf7332 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web
、·# especially if it merges an updated upstream into a topic branch.
2026-02-05 10:48:52 +08:00
a2fb3dcba5 更新 2026-02-05 10:48:20 +08:00
lcw
c4dca8f769 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-02-05 10:47:01 +08:00
lcw
b306f2b03b lcw 2026-02-05 10:46:54 +08:00
d3b4e76544 更新 2026-02-04 12:39:31 +08:00
2a82feb59a 更新权限注册 2026-02-04 12:36:44 +08:00
db3e3ee82f 更新 2026-02-04 12:03:08 +08:00
c8c130093f 更新页面 2026-02-04 11:50:44 +08:00
c18ce8ff0e 更新页面 2026-02-04 10:32:58 +08:00
7d61f83463 更新 2026-02-03 18:00:05 +08:00
da05ca015e 更新 2026-02-02 10:42:28 +08:00
a129e6d3f4 更新 2026-02-02 10:33:58 +08:00
2ea24d36f2 更新 2026-01-31 17:26:24 +08:00
dfe6036489 更新 2026-01-31 17:12:04 +08:00
a8b39af475 更新 2026-01-31 17:10:40 +08:00
fa4b36bd8c 更新 2026-01-31 16:48:47 +08:00
2cc924d091 更新 2026-01-31 15:01:31 +08:00
06453b284c 更新 2026-01-31 14:59:39 +08:00
4ad9f4976f 更新 2026-01-30 12:10:31 +08:00
39cf4b27f5 更新 2026-01-29 17:45:42 +08:00
62db6672f6 新增页面 2026-01-29 16:47:04 +08:00
5a1fc57019 更新 2026-01-29 10:33:37 +08:00
c606d6e8fd 更新 2026-01-28 19:21:00 +08:00
d003d7a20e 更新页面 2026-01-28 18:54:37 +08:00
d75295e756 更新 2026-01-28 18:43:40 +08:00
1390662e4d 更新大屏 2026-01-28 18:40:46 +08:00
5545659aee 更新 2026-01-28 16:56:02 +08:00
2635c76e79 更新布控 2026-01-28 16:40:47 +08:00
0e5a9c710d 更新 2026-01-28 16:15:40 +08:00
861c1168e7 更新 2026-01-28 10:10:25 +08:00
f7a83c1541 更新页面 2026-01-27 18:14:10 +08:00
105d13e8cb 更新 2026-01-27 17:28:36 +08:00
9e09db7f49 更新 2026-01-27 17:22:12 +08:00
390ef86532 更新 2026-01-27 10:10:33 +08:00
4f70b13ab7 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-01-27 09:43:44 +08:00
8c66561605 更新 2026-01-27 09:42:38 +08:00
lcw
65bc52b352 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-01-26 23:34:58 +08:00
lcw
2ceaa966cf lcw 2026-01-26 23:34:51 +08:00
9b8e788e61 更新时间 2026-01-26 19:59:57 +08:00
13d206f497 更新 2026-01-26 19:54:57 +08:00
ba26f616ba 更新 2026-01-26 18:39:29 +08:00
756271abe1 更新 2026-01-26 18:18:52 +08:00
35a1a0d247 更新 2026-01-26 18:07:54 +08:00
5a651a1f90 更新 2026-01-26 18:03:42 +08:00
lcw
df187151d6 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-01-26 17:35:11 +08:00
lcw
c7671317c5 lcw 2026-01-26 17:35:04 +08:00
5ced373ffe 更新 2026-01-26 17:28:55 +08:00
lcw
1a61e26279 lcw 2026-01-26 17:27:28 +08:00
0bd4a31c67 更新 2026-01-26 17:16:48 +08:00
e41e2d5a32 更新 2026-01-26 16:03:21 +08:00
5db55d9e75 更新 2026-01-26 15:55:57 +08:00
5998eea6b1 更新 2026-01-26 14:38:32 +08:00
1a3c4f0ea9 更新 2026-01-25 21:29:59 +08:00
8b3494c95b 更新 2026-01-25 20:25:52 +08:00
20506c9608 更新 2026-01-25 20:08:19 +08:00
6629dfd39f 更新 2026-01-25 20:05:13 +08:00
f0bb0546a9 更新 2026-01-25 19:55:12 +08:00
0067d31b32 更新 2026-01-25 19:50:18 +08:00
606184075b 更新 2026-01-25 19:02:53 +08:00
f7d78768b0 更新页面 2026-01-25 18:56:52 +08:00
b301ece916 更新页面 2026-01-25 18:07:15 +08:00
8b34dba464 更新 2026-01-25 12:39:31 +08:00
e87494ae2e 解决冲突 2026-01-25 11:59:22 +08:00
bc98b0ecb1 更新后台后大屏 2026-01-25 11:55:12 +08:00
lcw
e6eb53e2ef Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-01-23 19:57:22 +08:00
lcw
c12bda629a lcw 2026-01-23 19:57:10 +08:00
a8904c2a67 更新页面 2026-01-23 16:39:34 +08:00
aedcfb6a99 更新 2026-01-23 16:10:54 +08:00
1a20be46f5 Merge branch 'main' of http://61.139.16.27:26684/zy_oyj/sgxt_web 2026-01-23 15:48:31 +08:00
1ace24ec06 更新 2026-01-23 15:48:16 +08:00
174 changed files with 14523 additions and 4775 deletions

14
package-lock.json generated
View File

@ -38,7 +38,7 @@
"moment": "^2.30.1", "moment": "^2.30.1",
"ol": "^6.14.1", "ol": "^6.14.1",
"pinia": "^3.0.1", "pinia": "^3.0.1",
"pizzip": "^3.1.5", "pizzip": "^3.2.0",
"siriwave": "2.3.0", "siriwave": "2.3.0",
"tesseract.js": "^6.0.1", "tesseract.js": "^6.0.1",
"vue": "^3.2.8", "vue": "^3.2.8",
@ -13996,9 +13996,9 @@
} }
}, },
"node_modules/pizzip": { "node_modules/pizzip": {
"version": "3.1.5", "version": "3.2.0",
"resolved": "https://registry.npmmirror.com/pizzip/-/pizzip-3.1.5.tgz", "resolved": "https://registry.npmmirror.com/pizzip/-/pizzip-3.2.0.tgz",
"integrity": "sha512-uQXb7woLr9baq43Z9EY4wD5cpzrXQd6QUEwehreC1HyRuE4Q1UaGVG9/aCL4CqM4SMz47iE1UyrGtyzmleWHhQ==", "integrity": "sha512-X4NPNICxCfIK8VYhF6wbksn81vTiziyLbvKuORVAmolvnUzl1A1xmz9DAWKxPRq9lZg84pJOOAMq3OE61bD8IQ==",
"dependencies": { "dependencies": {
"pako": "^2.1.0" "pako": "^2.1.0"
} }
@ -31902,9 +31902,9 @@
} }
}, },
"pizzip": { "pizzip": {
"version": "3.1.5", "version": "3.2.0",
"resolved": "https://registry.npmmirror.com/pizzip/-/pizzip-3.1.5.tgz", "resolved": "https://registry.npmmirror.com/pizzip/-/pizzip-3.2.0.tgz",
"integrity": "sha512-uQXb7woLr9baq43Z9EY4wD5cpzrXQd6QUEwehreC1HyRuE4Q1UaGVG9/aCL4CqM4SMz47iE1UyrGtyzmleWHhQ==", "integrity": "sha512-X4NPNICxCfIK8VYhF6wbksn81vTiziyLbvKuORVAmolvnUzl1A1xmz9DAWKxPRq9lZg84pJOOAMq3OE61bD8IQ==",
"requires": { "requires": {
"pako": "^2.1.0" "pako": "^2.1.0"
} }

View File

@ -39,7 +39,7 @@
"moment": "^2.30.1", "moment": "^2.30.1",
"ol": "^6.14.1", "ol": "^6.14.1",
"pinia": "^3.0.1", "pinia": "^3.0.1",
"pizzip": "^3.1.5", "pizzip": "^3.2.0",
"siriwave": "2.3.0", "siriwave": "2.3.0",
"tesseract.js": "^6.0.1", "tesseract.js": "^6.0.1",
"vue": "^3.2.8", "vue": "^3.2.8",

View File

@ -7,7 +7,6 @@
</keep-alive> </keep-alive>
</router-view> </router-view>
<Fzq /> <Fzq />
</template> </template>
<script setup> <script setup>
import Watermark from "@/components/Watermark.vue"; import Watermark from "@/components/Watermark.vue";
@ -156,6 +155,7 @@ v-deep .el-loading-mask {
transform: translateY(-50%) translateX(-50%); transform: translateY(-50%) translateX(-50%);
} }
.popupCustomBox{ .popupCustomBox{
width: 130px;
position: relative; position: relative;
background: rgba(2, 55, 114, 0.99); background: rgba(2, 55, 114, 0.99);
color: #fff; color: #fff;
@ -191,9 +191,11 @@ v-deep .el-loading-mask {
line-height: 22px; line-height: 22px;
text-transform: none; text-transform: none;
margin-bottom: 0; margin-bottom: 0;
display: flex;
justify-content: space-between;
span{ span{
display: inline-block; display: inline-block;
width: 45px; width: 60px;
text-align: center; text-align: center;
} }
} }

View File

@ -93,3 +93,43 @@ export const ypbgSjzlYpsp = (data) => {
// / mosty - api / mosty - gsxt / ypbg / sjzl / sendFqzl // / mosty - api / mosty - gsxt / ypbg / sjzl / sendFqzl
// 工作流审批回掉 // 工作流审批回掉
// / mosty - api / mosty - gsxt / ypbg / sjzl / updateBkgzl // / mosty - api / mosty - gsxt / ypbg / sjzl / updateBkgzl
// /gsxtYpbg/getPageList 获取列表
export const gsxtYpbgGetPageList = (params) => {
return request({
url: api + `/gsxtYpbg/getPageList`,
method: "get",
params
})
};
// /gsxtYpbg/deleteEntity删除
export const gsxtYpbgDeleteEntity = (data) => {
return request({
url: api + `/gsxtYpbg/deleteEntity`,
method: "delete",
data
})
};
// /gsxtYpbg/addEntity 新增
export const gsxtYpbgAddEntity = (data) => {
return request({
url: api + `/gsxtYpbg/addEntity`,
method: "post",
data
})
};
// /gsxtYpbg/editEntity 修改
export const gsxtYpbgEditEntity = (data) => {
return request({
url: api + `/gsxtYpbg/editEntity`,
method: "put",
data
})
};
// /gsxtYpbg/{id} 详情
export const gsxtYpbgId=(id) => {
return request({
url: api + `/gsxtYpbg/${id}`,
method: "get"
})
};

View File

@ -207,3 +207,19 @@ export const jqypfxbgCzlfx = (params) => {
params params
}); });
} }
// 网络舆情
export const gsxtWlyqGetPageList = (params) => {
return request({
url: api + "/gsxt/wlyq/getPageList",
method: "GET",
params
});
}
export const gsxtWlyqSelectById = (id) => {
return request({
url: api + `/gsxt/wlyq/selectById/${id}`,
method: "GET",
});
}

BIN
src/assets/images/cjyp.mp3 Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/images/xsyp.mp3 Normal file

Binary file not shown.

BIN
src/assets/images/ypbg.mp3 Normal file

Binary file not shown.

BIN
src/assets/images/ypzl.mp3 Normal file

Binary file not shown.

View File

@ -1,5 +1,12 @@
<template> <template>
<DraggableResizableVue v-if="props.modelValue" <div class="mimiBox flex" @click="handleWindowSize" v-show="isMinimized" >
<div class="item mr5 one"></div>
<div class="item mr5 two"></div>
<div class="item mr5 three"></div>
<div class="item mr5 four"></div>
<div class="item mr5 five"></div>
</div>
<DraggableResizableVue v-show="!isMinimized"
v-model:x="element.x" v-model:x="element.x"
v-model:y="element.y" v-model:y="element.y"
v-model:h="element.height" v-model:h="element.height"
@ -19,17 +26,17 @@
<div class="conference-header"> <div class="conference-header">
<div class="header-top"> <div class="header-top">
<div class="title-section" v-show="displaySubject"> <div class="title-section" v-show="displaySubject">
<h3 v-if="!editSubject" @click="editSubject = true" class="conference-title"> <h3 v-if="!editSubject" @click="editSubject = true" class="conference-title">{{ displaySubject }} </h3>
{{ displaySubject }}
</h3>
<el-input v-else v-model="subject" autofocus allow-clear @blur="updateSubject" class="title-input"/> <el-input v-else v-model="subject" autofocus allow-clear @blur="updateSubject" class="title-input"/>
<div class="meeting-id-tag" @click="copyMeetingNumber" v-if="activeMeetingConfig?.meeting?.number"> <div class="meeting-id-tag" @click="copyMeetingNumber" v-if="activeMeetingConfig?.meeting?.number">
<span class="id-label">会议号:</span> <span class="id-label">会议号:</span>
<span class="id-value">{{ activeMeetingConfig?.meeting?.number }}</span> <span class="id-value">{{ activeMeetingConfig?.meeting?.number }}</span>
<el-icon class="copy-icon"><CopyDocument /></el-icon> <el-icon class="copy-icon"><CopyDocument /></el-icon>
</div> </div>
</div> </div>
<div style="color: #999999;padding-right: 30px;">
<el-icon size="18px" @click="handleWindowSize"><Minus /></el-icon>
</div>
</div> </div>
<div class="participants-info"> <div class="participants-info">
<el-icon><User /></el-icon> <el-icon><User /></el-icon>
@ -75,17 +82,22 @@
<div class="control-bar"> <div class="control-bar">
<!-- 锁定 --> <!-- 锁定 -->
<div class="flex dir-column align-center">
<el-button circle @click="lockConference" class="control-btn"> <el-button circle @click="lockConference" class="control-btn">
<el-icon size="20px" v-if="activeMeetingConfig?.lockStatus == 1"><Lock/></el-icon> <el-icon size="24px" v-if="activeMeetingConfig?.lockStatus == 1"><Lock/></el-icon>
<el-icon size="20px" v-else ><Unlock/></el-icon> <el-icon size="24px" v-else ><Unlock/></el-icon>
</el-button> </el-button>
<div>{{ activeMeetingConfig?.lockStatus == 1 ? '已锁定' : '未锁定' }}</div>
</div>
<!-- 麦克风 --> <!-- 麦克风 -->
<div class="flex dir-column align-center">
<el-button circle @click="setMuteMic" class="control-btn"> <el-button circle @click="setMuteMic" class="control-btn">
<img v-if="isMicEnable" src="@/assets/images/webPuc/svgs/microphone.svg" alt=""> <img v-if="isMicEnable" src="@/assets/images/webPuc/svgs/microphone.svg" alt="">
<img v-else src="@/assets/images/webPuc/svgs/microphone_mute.svg" alt=""> <img v-else src="@/assets/images/webPuc/svgs/microphone_mute.svg" alt="">
</el-button> </el-button>
<div>麦克风</div>
</div>
<el-popover title="选择麦克风" trigger="click" position="bottom-end"> <el-popover title="选择麦克风" trigger="click" position="bottom-end">
<template #reference> <template #reference>
<el-icon class="control-arrow" color="#fff"><ArrowDown/></el-icon> <el-icon class="control-arrow" color="#fff"><ArrowDown/></el-icon>
@ -94,10 +106,14 @@
</el-popover> </el-popover>
<!-- 扬声器 --> <!-- 扬声器 -->
<div class="flex dir-column align-center">
<el-button circle @click="setMuteEar" class="control-btn"> <el-button circle @click="setMuteEar" class="control-btn">
<img v-if="audioOuputStatus == 1" src="@/assets/images/webPuc/svgs/earpiece.svg" alt=""> <img v-if="audioOuputStatus == 1" src="@/assets/images/webPuc/svgs/earpiece.svg" alt="">
<img v-else src="@/assets/images/webPuc/svgs/trumpet_mute.svg" alt=""> <img v-else src="@/assets/images/webPuc/svgs/trumpet_mute.svg" alt="">
</el-button> </el-button>
<div>扬声器</div>
</div>
<el-popover title="选择扬声器" trigger="click" position="bottom-end"> <el-popover title="选择扬声器" trigger="click" position="bottom-end">
<template #reference> <template #reference>
<el-icon class="control-arrow" color="#fff"><ArrowDown/></el-icon> <el-icon class="control-arrow" color="#fff"><ArrowDown/></el-icon>
@ -106,10 +122,13 @@
</el-popover> </el-popover>
<!-- 摄像头 --> <!-- 摄像头 -->
<div class="flex dir-column align-center">
<el-button circle @click="setCamera" class="control-btn"> <el-button circle @click="setCamera" class="control-btn">
<img v-if="userInfo?.camera_status === CAMERA_STATUS_OPEN" src="@/assets/images/webPuc/svgs/camera.svg" alt=""> <img v-if="userInfo?.camera_status === CAMERA_STATUS_OPEN" src="@/assets/images/webPuc/svgs/camera.svg" alt="">
<img v-else src="@/assets/images/webPuc/svgs/camera_mute.svg" alt=""> <img v-else src="@/assets/images/webPuc/svgs/camera_mute.svg" alt="">
</el-button> </el-button>
<div>摄像头</div>
</div>
<el-popover title="选择摄像头" trigger="click" position="bottom-end"> <el-popover title="选择摄像头" trigger="click" position="bottom-end">
<template #reference> <template #reference>
<el-icon class="control-arrow" color="#fff"><ArrowDown/></el-icon> <el-icon class="control-arrow" color="#fff"><ArrowDown/></el-icon>
@ -118,64 +137,72 @@
</el-popover> </el-popover>
<!-- 屏幕共享 --> <!-- 屏幕共享 -->
<div class="flex dir-column align-center">
<el-button circle @click="setShareScreenStatus(1)" class="control-btn"> <el-button circle @click="setShareScreenStatus(1)" class="control-btn">
<img src="@/assets/images/webPuc/svgs/share_video.svg" alt=""> <img src="@/assets/images/webPuc/svgs/share_video.svg" alt="">
</el-button> </el-button>
<div>屏幕共享</div>
</div>
<!-- 结束共享 / 结束会议 (Center) --> <!-- 结束共享 / 结束会议 (Center) -->
<el-button v-if="activeMeetingConfig?.sharingMember?.basedata_id === userInfo?.basedata_id" <el-button v-if="activeMeetingConfig?.sharingMember?.basedata_id === userInfo?.basedata_id" type="danger" shape="round" status="danger" class="hangup-btn" @click="setShareScreenStatus(0)">结束共享</el-button>
type="danger"
shape="round"
status="danger"
class="hangup-btn"
@click="setShareScreenStatus(0)">
结束共享
</el-button>
<template v-else>
<!-- 结束会议 v-if="globalStore.IS_CURRENT_MEETING_OWNER"--> <!-- 结束会议 v-if="globalStore.IS_CURRENT_MEETING_OWNER"-->
<el-button <el-button v-else type="danger" shape="round" class="hangup-btn" @click="endConference">结束会议</el-button>
type="danger"
shape="round"
class="hangup-btn"
@click="endConference">
结束会议
</el-button>
</template>
<!-- 成员管理 --> <!-- 成员管理 -->
<div class="flex dir-column align-center">
<el-button circle @click="showMembers" class="control-btn"> <el-button circle @click="showMembers" class="control-btn">
<el-icon color="#fff" size="20"><Auatar/></el-icon> <el-icon color="#fff" size="24px"><Grid /></el-icon>
</el-button> </el-button>
<div>成员管理</div>
</div>
<!-- 语音激励 --> <!-- 语音激励 -->
<div class="flex dir-column align-center">
<el-button circle @click="setVoiceStimulation()" class="control-btn"> <el-button circle @click="setVoiceStimulation()" class="control-btn">
<img v-if="activeMeetingConfig?.voiceStimulation" src="@/assets/images/webPuc/svgs/icon_embrave.svg" alt=""> <img v-if="activeMeetingConfig?.voiceStimulation" src="@/assets/images/webPuc/svgs/icon_embrave.svg" alt="">
<img v-else src="@/assets/images/webPuc/svgs/conference_icom_cancel_voice_stimulation.svg" alt=""> <img v-else src="@/assets/images/webPuc/svgs/conference_icom_cancel_voice_stimulation.svg" alt="">
</el-button> </el-button>
<div>语音激励</div>
</div>
<!-- 布局 --> <!-- 布局 -->
<!-- <LaoutType @setConfernceLayoutType="setConfernceLayoutType" /> --> <!-- <LaoutType @setConfernceLayoutType="setConfernceLayoutType" /> -->
<!-- 画面抓取-截图 --> <!-- 画面抓取-截图 -->
<div class="flex dir-column align-center">
<el-button circle @click="startScreenshot" class="control-btn"> <el-button circle @click="startScreenshot" class="control-btn">
<el-icon color="#fff" size="20"><Scissor/></el-icon> <el-icon color="#fff" size="24px"><Scissor/></el-icon>
</el-button> </el-button>
<div>截图</div>
</div>
<!-- 视频广播 --> <!-- 视频广播 -->
<div class="flex dir-column align-center">
<el-button circle @click="broadcastAction" class="control-btn"> <el-button circle @click="broadcastAction" class="control-btn">
<img src="@/assets/images/webPuc/svgs/icon_broadcast.svg" alt=""> <img src="@/assets/images/webPuc/svgs/icon_broadcast.svg" alt="">
</el-button> </el-button>
<div>视频广播</div>
</div>
<!-- 录屏 --> <!-- 录屏 -->
<div class="flex dir-column align-center">
<el-button circle @click="!isRecording ? mediaRecorder.start() : mediaRecorder.stop()" class="control-btn"> <el-button circle @click="!isRecording ? mediaRecorder.start() : mediaRecorder.stop()" class="control-btn">
<el-icon v-if="!isRecording"><Camera/></el-icon> <el-icon size="24px" v-if="!isRecording"><Camera/></el-icon>
<el-icon v-else style="color: red"><Videopause/></el-icon> <el-icon size="24px" v-else style="color: red"><Videopause/></el-icon>
</el-button> </el-button>
<div>{{ isRecording ? '录屏':'停止' }}</div>
</div>
<div class="flex dir-column align-center">
<el-button circle @click="toggleFullscreen" class="control-btn"> <el-button circle @click="toggleFullscreen" class="control-btn">
<el-icon v-if="!isFullscreen"><svg class="icon" width="200" height="200" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M384 192H192a64 64 0 00-64 64v192a32 32 0 1064 0V288h192a32 32 0 000-64zm384 64H576a32 32 0 100 64h192v160a32 32 0 1064 0V256a64 64 0 00-64-64zM352 768H192V608a32 32 0 10-64 0v192a64 64 0 0064 64h160a32 32 0 100-64zm544-160a32 32 0 00-32 32v128H704a32 32 0 100 64h160a64 64 0 0064-64V640a32 32 0 00-32-32z"/></svg></el-icon> <el-icon size="24px" v-if="!isFullscreen"><svg class="icon" width="200" height="200" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M384 192H192a64 64 0 00-64 64v192a32 32 0 1064 0V288h192a32 32 0 000-64zm384 64H576a32 32 0 100 64h192v160a32 32 0 1064 0V256a64 64 0 00-64-64zM352 768H192V608a32 32 0 10-64 0v192a64 64 0 0064 64h160a32 32 0 100-64zm544-160a32 32 0 00-32 32v128H704a32 32 0 100 64h160a64 64 0 0064-64V640a32 32 0 00-32-32z"/></svg></el-icon>
<el-icon v-else><svg class="icon" width="200" height="200" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M352 288a32 32 0 010-64h160a32 32 0 0132 32v160a32 32 0 11-64 0V320H352zm320 448a32 32 0 010 64H512a32 32 0 01-32-32V608a32 32 0 1164 0v128h128zM256 672a32 32 0 00-32-32H96a32 32 0 00-32 32v128a32 32 0 1064 0v-96h64a32 32 0 0032-32zm640-384a32 32 0 00-32 32v96h-64a32 32 0 100 64h128a32 32 0 0032-32V288a32 32 0 00-32-32z"/></svg></el-icon> <el-icon size="24px" v-else ><svg class="icon" width="200" height="200" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path fill="currentColor" d="M352 288a32 32 0 010-64h160a32 32 0 0132 32v160a32 32 0 11-64 0V320H352zm320 448a32 32 0 010 64H512a32 32 0 01-32-32V608a32 32 0 1164 0v128h128zM256 672a32 32 0 00-32-32H96a32 32 0 00-32 32v128a32 32 0 1064 0v-96h64a32 32 0 0032-32zm640-384a32 32 0 00-32 32v96h-64a32 32 0 100 64h128a32 32 0 0032-32V288a32 32 0 00-32-32z"/></svg></el-icon>
</el-button> </el-button>
<div>{{ !isFullscreen ? '全屏':'退出' }}</div>
</div>
</div> </div>
</div> </div>
@ -773,6 +800,18 @@ const setAudio = (stream) => {
} }
}; };
const isMinimized = ref(false);
const lastHeight = ref(0);
// 最小化
function handleWindowSize() {
isMinimized.value = !isMinimized.value;
if (isMinimized.value) {
lastHeight.value = element.value.height;
element.value.height = 70;
} else {
element.value.height = lastHeight.value;
}
}
onMounted(()=>{ onMounted(()=>{
console.log(globalStore,'=====0000000000000'); console.log(globalStore,'=====0000000000000');
@ -795,6 +834,7 @@ onMounted(()=>{
}); });
onUnmounted(() => { onUnmounted(() => {
emitter.off('onMediaStream'); emitter.off('onMediaStream');
emitter.off('onHangup'); emitter.off('onHangup');
@ -804,7 +844,67 @@ onUnmounted(() => {
</script> </script>
<style scoped>
<style scoped lang="scss">
.mimiBox {
position: absolute;
top: 10px;
right: 20px;
display: flex;
align-items: flex-end;
padding: 6px 8px;
border-radius: 16px;
background: rgba(0, 0, 0, 0.6);
cursor: pointer;
}
.mimiBox .item {
width: 3px;
height: 14px;
margin-right: 3px;
background: linear-gradient(180deg, #4facfe 0%, #00f2fe 100%);
border-radius: 999px;
animation: sound-wave 1s ease-in-out infinite;
transform-origin: bottom;
}
.mimiBox .item:last-child {
margin-right: 0;
}
.mimiBox .item:nth-child(1) {
animation-delay: 0s;
}
.mimiBox .item:nth-child(2) {
animation-delay: 0.15s;
}
.mimiBox .item:nth-child(3) {
animation-delay: 0.3s;
}
.mimiBox .item:nth-child(4) {
animation-delay: 0.45s;
}
.mimiBox .item:nth-child(5) {
animation-delay: 0.6s;
}
@keyframes sound-wave {
0%,
100% {
transform: scaleY(0.4);
opacity: 0.7;
}
50% {
transform: scaleY(1.4);
opacity: 1;
}
}
.container { .container {
position: absolute; position: absolute;
display: flex; display: flex;

View File

@ -144,58 +144,58 @@ export function MapUtil(map) {
} }
// 展示气泡框 // 展示气泡框
MapUtil.prototype.makerPopup = (val)=>{ MapUtil.prototype.makerPopup = (val) => {
let { data,flag,type = 'Dark'} = val let { data, flag, type = 'Dark' } = val
// Dark Light Custom // Dark Light Custom
let marker; let marker;
if(!_that._self[flag]) _that._self[flag] = []; if (!_that._self[flag]) _that._self[flag] = [];
if(type == 'Dark' || type == 'Light') { if (type == 'Dark' || type == 'Light') {
let list = zdyContent(flag,data);// 默认的样式 let list = zdyContent(flag, data);// 默认的样式
marker = map.createPopup([data.jd,data.wd],{ marker = map.createPopup([data.jd, data.wd], {
style:style, // 气泡框样式: style: style, // 气泡框样式:
data:list, data: list,
title:data.ssbm, title: data.ssbm,
closeButton:false, closeButton: false,
anchor:'bottom', anchor: 'bottom',
pixelOffset:[0,-50] pixelOffset: [0, -50]
}) })
}else { } else {
marker = map.createPopup([data.jd,data.wd],{ marker = map.createPopup([data.jd, data.wd], {
style:'Custom', // // 自定义样式 style: 'Custom', // // 自定义样式
attrs:{ attrs: {
class:'popupCustom' class: 'popupCustom'
}, },
container: zdyContentHtml(flag,data), container: zdyContentHtml(flag, data),
closeButton:false, closeButton: false,
anchor:'bottom', anchor: 'bottom',
pixelOffset:[0,-30] pixelOffset: [0, -30]
}) })
} }
_that._self[flag].push(marker) _that._self[flag].push(marker)
} }
// 弹窗自定义默认内容 // 弹窗自定义默认内容
function zdyContent(flag,item){ function zdyContent(flag, item) {
switch (flag) { switch (flag) {
case 'hm': case 'hm':
return [ return [
{ label:'林安码线索数量',value:item.lamsx }, { label: '林安码线索数量', value: item.lamsx },
{ label:'布控预警数量',value:item.bkyj }, { label: '布控预警数量', value: item.bkyj },
{ label:'红色预警数量',value:item.hsyj }, { label: '红色预警数量', value: item.hsyj },
{ label:'信息采集数量',value:item.xxcjsl }, { label: '信息采集数量', value: item.xxcjsl },
] ]
} }
} }
// 弹窗自定义标签内容 // 弹窗自定义标签内容
function zdyContentHtml(flag,item){ function zdyContentHtml(flag, item) {
let html = '' let html = ''
switch (flag) { switch (flag) {
case 'hm_pop': case 'hm_pop':
const list = [ const list = [
{ jb: "一级",sl:'5',ypl:'100%' }, { jb: "一级", sl: '5' },
{ jb: "二级",sl:'5',ypl:'100%' }, { jb: "二级", sl: '5' },
{ jb: "三级",sl:'3',ypl:'60%' }, { jb: "三级", sl: '3' },
{ jb: "四级",sl:'0',ypl:'20%' } { jb: "四级", sl: '0' }
]; ];
html = ` html = `
<div class="popupCustomBox"> <div class="popupCustomBox">
@ -204,8 +204,8 @@ export function MapUtil(map) {
<span>今日警情${item.jrzs || 0}</span> <span>今日警情${item.jrzs || 0}</span>
</div> </div>
<ul> <ul>
<li class="popupCustomTitle_li"><span>级别</span> <span>数量</span> <span>研判率</span> </li> <li class="popupCustomTitle_li"><span>数据来源</span> <span>数量</span> </li>
${item.jqjb.map(it => `<li class="popupCustomTitle_li"><span>${it.jbmc}</span> <span>${it.jrsl}</span> <span>${it.ypbl}</span></li>`).join('')} ${item.jrtj.map(it => `<li class="popupCustomTitle_li"><span>${it.lyms}</span> <span>${it.jrsl}</span> </li>`).join('')}
</ul> </ul>
</div> </div>
` `

View File

@ -132,10 +132,18 @@ const props = defineProps({
tableHeight: { tableHeight: {
type: Number || String, type: Number || String,
}, },
// 在自动滚动中,想滚动到底部,是否请求下一页
hasNext: {
type: Number,
default: false
},
// 自动滚动
isScroll: { isScroll: {
type: Number, type: Number,
default: false default: false
}, },
customClass: { customClass: {
type: String type: String
}, },
@ -333,6 +341,8 @@ const createScroll = () => {
timer.value = setInterval(() => { timer.value = setInterval(() => {
target.scrollTop += 1; target.scrollTop += 1;
if (target.scrollTop >= originalBodyHeight.value) { if (target.scrollTop >= originalBodyHeight.value) {
// 滚动到底部没有下一页了,循环滚动 ,
if(props.hasNext) emit("changePage");
target.scrollTop -= originalBodyHeight.value; target.scrollTop -= originalBodyHeight.value;
} }
}, 20); }, 20);

View File

@ -26,7 +26,7 @@
<el-table-column v-for="(item, index) in tableColumn" :align="getConfiger?.align" :prop="item.prop" :key="index" <el-table-column v-for="(item, index) in tableColumn" :align="getConfiger?.align" :prop="item.prop" :key="index"
:label="item.label" :width="item.width" style="width: 100%; font-size: 14px" :label="item.label" :width="item.width" style="width: 100%; font-size: 14px"
:show-overflow-tooltip="item.showOverflowTooltip || false" :sortable="item.sortable || false"> :show-overflow-tooltip="item.showOverflowTooltip || true" :sortable="item.sortable || false">
<!-- 使用自定义 --> <!-- 使用自定义 -->
<template v-if="item.showSolt" #default="scope"> <template v-if="item.showSolt" #default="scope">
<slot :name="item.prop" v-bind="scope"></slot> <slot :name="item.prop" v-bind="scope"></slot>

View File

@ -415,6 +415,13 @@ const reset = () => {
emit("reset", true); emit("reset", true);
emit("submit", searchObj); emit("submit", searchObj);
}; };
// 暴露searchObj给父组件
defineExpose({
searchObj,
submit,
reset
});
watchEffect(() => { watchEffect(() => {
loadingPage.value = true; loadingPage.value = true;
let arr = JSON.parse(JSON.stringify(props.searchArr)); let arr = JSON.parse(JSON.stringify(props.searchArr));

View File

@ -0,0 +1,240 @@
<template>
<div class="test-div" v-if="dataList && dataList.length > 0">
<div class="test-header">
<span class="test-title">消息通知</span>
<div class="header-right">
<span class="test-countdown">{{ countdown }}s</span>
<el-icon class="close-icon" @click="handleClose">
<Close />
</el-icon>
</div>
</div>
<div class="test-content">
<Item v-for="(item, index) in dataList" :key="index" :item="item" />
</div>
</div>
</template>
<script setup>
// 测试div组件用于在后台和大屏页面都显示
import { ref, onMounted, onUnmounted } from 'vue'
import { Close } from '@element-plus/icons-vue'
import WebSoketClass from '@/utils/webSocket.js'
import emitter from "@/utils/eventBus.js"; // 导入事件总线
import Item from './item.vue'
import { AudioPlayerClass } from '@/utils/audioPlayer.js'
const webSoket = new WebSoketClass()
const dataList = ref([])
const timekeeping = ref(null)
const countdown = ref(0) // 倒计时时间(秒)
// 音频播放器实例映射
const audioPlayers = ref({
'02': null, // 信息上报
'03': null, // 研判审批
'04': null, // 研判指令
'05': null // 线索下发
})
// 音频文件路径映射
const audioPaths = {
'02': require('@/assets/images/cjyp.mp3'),
'03': require('@/assets/images/ypbg.mp3'),
'04': require('@/assets/images/ypzl.mp3'),
'05': require('@/assets/images/xsyp.mp3')
}
// 初始化音频播放器
const initAudioPlayers = () => {
Object.keys(audioPaths).forEach(type => {
try {
audioPlayers.value[type] = new AudioPlayerClass()
audioPlayers.value[type].init(audioPaths[type], false)
} catch (error) {
console.error(`初始化类型${type}的音频播放器失败:`, error)
}
})
}
// 根据类型播放音频
const playAudioByType = (type) => {
if (audioPlayers.value[type]) {
try {
audioPlayers.value[type].play()
} catch (error) {
console.error(`播放类型${type}的音频失败:`, error)
}
}
}
// 手动关闭
const handleClose = () => {
if (timekeeping.value) {
clearInterval(timekeeping.value)
timekeeping.value = null
}
dataList.value = []
}
// 重置倒计时
const resetCountdown = () => {
if (timekeeping.value) {
clearInterval(timekeeping.value)
}
countdown.value = 15
timekeeping.value = setInterval(() => {
countdown.value--
if (countdown.value <= 0) {
clearInterval(timekeeping.value)
dataList.value = []
timekeeping.value = null
}
}, 1000)
}
onMounted(() => {
// 初始化音频播放器
initAudioPlayers()
emitter.on('webSocketMessage', (newsDate) => {
if (newsDate) {
dataList.value.unshift({...newsDate.data,typeMasgeLx:newsDate.type})
// 根据消息类型播放音频
playAudioByType(newsDate.type)
resetCountdown()
}
})
// 组件挂载时执行的操作
webSoket.connect()
console.log('组件挂载时执行的操作')
})
onUnmounted(() => {
webSoket.closeConnection()
emitter.off('webSocketMessage')
if (timekeeping.value) {
clearInterval(timekeeping.value)
}
// 销毁所有音频播放器实例
Object.values(audioPlayers.value).forEach(player => {
if (player) {
player.destroy()
}
})
// 组件卸载时执行的操作
console.log('组件卸载时执行的操作')
})
</script>
<style scoped lang="scss">
.test-div {
width: 400px;
max-height: 250px;
position: fixed;
bottom: 2%;
right: 2%;
z-index: 1999;
background: linear-gradient(135deg, #0a3b6d 0%, #1a5a9e 100%);
border: 1px solid rgba(0, 255, 255, 0.3);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 255, 255, 0.3), 0 0 20px rgba(0, 255, 255, 0.1);
overflow: hidden;
animation: slideIn 0.3s ease-out;
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
}
.test-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background: rgba(0, 255, 255, 0.1);
border-bottom: 1px solid rgba(0, 255, 255, 0.3);
}
.test-title {
font-size: 16px;
font-weight: bold;
color: #00ffff;
display: flex;
align-items: center;
gap: 8px;
text-shadow: 0 0 10px rgba(0, 255, 255, 0.7);
&::before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
background-color: #00ffff;
border-radius: 50%;
box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
transform: scale(1);
box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
}
50% {
opacity: 0.8;
transform: scale(1.2);
box-shadow: 0 0 20px rgba(0, 255, 255, 1);
}
}
}
.header-right {
display: flex;
align-items: center;
gap: 10px;
}
.test-countdown {
font-size: 14px;
color: #00ffff;
background: rgba(0, 255, 255, 0.1);
padding: 4px 12px;
border: 1px solid rgba(0, 255, 255, 0.3);
border-radius: 12px;
font-weight: 500;
text-shadow: 0 0 5px rgba(0, 255, 255, 0.5);
}
.close-icon {
font-size: 18px;
color: #00ffff;
cursor: pointer;
transition: all 0.3s ease;
padding: 4px;
border-radius: 4px;
text-shadow: 0 0 5px rgba(0, 255, 255, 0.5);
&:hover {
background: rgba(0, 255, 255, 0.2);
transform: rotate(90deg);
box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
}
}
.test-content {
max-height: 150px;
overflow-y: auto;
padding: 12px;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
&::-webkit-scrollbar {
display: none; /* Chrome, Safari and Opera */
}
}
</style>

View File

@ -0,0 +1,284 @@
<template>
<div class="test-div" v-if="dataList && dataList.length > 0">
<div class="test-header">
<span class="test-title">消息通知</span>
<div class="header-right">
<span class="test-countdown">{{ countdown }}s</span>
<el-icon class="close-icon" @click="handleClose">
<Close />
</el-icon>
</div>
</div>
<div class="test-content">
<Item v-for="(item, index) in dataList" :key="index" :item="item" />
</div>
</div>
</template>
<script setup>
// 测试div组件用于在后台和大屏页面都显示
import { ref, onMounted, onUnmounted } from 'vue'
import { Close } from '@element-plus/icons-vue'
import emitter from "@/utils/eventBus.js"; // 导入事件总线
import { qcckGet } from '@/api/qcckApi'
import Item from './item.vue'
import { AudioPlayerClass } from '@/utils/audioPlayer.js'
import {getItem} from '@/utils/storage.js'
const dataList = ref([])
const timekeeping = ref(null)
const countdown = ref(0) // 倒计时时间(秒)
// 音频播放器实例映射
const audioPlayers = ref({
'02': null, // 信息上报
'03': null, // 研判审批
'04': null, // 研判指令
'05': null // 线索下发
})
// 音频文件路径映射
const audioPaths = {
'02': require('@/assets/images/cjyp.mp3'),
'03': require('@/assets/images/ypbg.mp3'),
'04': require('@/assets/images/ypzl.mp3'),
'05': require('@/assets/images/xsyp.mp3')
}
// 初始化音频播放器
const initAudioPlayers = () => {
Object.keys(audioPaths).forEach(type => {
try {
audioPlayers.value[type] = new AudioPlayerClass()
audioPlayers.value[type].init(audioPaths[type], false)
} catch (error) {
console.error(`初始化类型${type}的音频播放器失败:`, error)
}
})
}
// 根据类型播放音频
const playAudioByType = (type) => {
if (audioPlayers.value[type]) {
try {
audioPlayers.value[type].play()
} catch (error) {
console.error(`播放类型${type}的音频失败:`, error)
}
}
}
// 手动关闭
const handleClose = () => {
if (timekeeping.value) {
clearInterval(timekeeping.value)
timekeeping.value = null
}
dataList.value = []
}
// 重置倒计时
const resetCountdown = () => {
if (timekeeping.value) {
clearInterval(timekeeping.value)
}
countdown.value = 15
timekeeping.value = setInterval(() => {
countdown.value--
if (countdown.value <= 0) {
clearInterval(timekeeping.value)
dataList.value = []
timekeeping.value = null
}
}, 1000)
}
// 做一个定时器15s一次
const checkNews = ref(null)
const checkNewsInterval = 15000 // 15秒
checkNews.value = setInterval(() => {
dataModel()
}, checkNewsInterval)
onMounted(() => {
// 初始化音频播放器
initAudioPlayers()
emitter.on('webSocketMessage', (newsDate) => {
if (newsDate) {
dataList.value = newsDate
// dataList.value.unshift({...newsDate.data,typeMasgeLx:newsDate.type})
// 根据消息类型播放音频
playAudioByType(newsDate[0].typeMasgeLx)
resetCountdown()
}
})
})
const idEntityCard = ref(getItem('idEntityCard'))
const dataModel = () => {
qcckGet({}, '/mosty-gsxt/dsjJbxx/message').then(res => {
if (res) {
const yjmasg = res.filter(item => item.type === '01')
if (yjmasg.length > 0) {
emitter.emit('openYp', yjmasg[0].obj); // 触发音频播放
} else {
const data=res.filter(item=>item.sfzList.includes(idEntityCard.value))
const infoMasge =data.map(item => {
return {
...item.obj,
typeMasgeLx: item.type
}
})
console.log(infoMasge);
emitter.emit('webSocketMessage', infoMasge)
}
}
})
}
// if (newsDate.type === '01') {
// // 触发音频播放
// console.log('触发音频播放');
// emitter.emit('openYp', newsDate.data); // 传递消息数据
// } else {
onUnmounted(() => {
emitter.off('webSocketMessage')
if (timekeeping.value) {
clearInterval(timekeeping.value)
}
// 销毁所有音频播放器实例
Object.values(audioPlayers.value).forEach(player => {
if (player) {
player.destroy()
}
})
// 清除定时器
if (checkNews.value) {
clearInterval(checkNews.value)
checkNews.value = null
}
// 组件卸载时执行的操作
console.log('组件卸载时执行的操作')
})
</script>
<style scoped lang="scss">
.test-div {
width: 400px;
max-height: 250px;
position: fixed;
bottom: 2%;
right: 2%;
z-index: 1999;
background: linear-gradient(135deg, #0a3b6d 0%, #1a5a9e 100%);
border: 1px solid rgba(0, 255, 255, 0.3);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 255, 255, 0.3), 0 0 20px rgba(0, 255, 255, 0.1);
overflow: hidden;
animation: slideIn 0.3s ease-out;
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
}
.test-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background: rgba(0, 255, 255, 0.1);
border-bottom: 1px solid rgba(0, 255, 255, 0.3);
}
.test-title {
font-size: 16px;
font-weight: bold;
color: #00ffff;
display: flex;
align-items: center;
gap: 8px;
text-shadow: 0 0 10px rgba(0, 255, 255, 0.7);
&::before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
background-color: #00ffff;
border-radius: 50%;
box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
}
50% {
opacity: 0.8;
transform: scale(1.2);
box-shadow: 0 0 20px rgba(0, 255, 255, 1);
}
}
}
.header-right {
display: flex;
align-items: center;
gap: 10px;
}
.test-countdown {
font-size: 14px;
color: #00ffff;
background: rgba(0, 255, 255, 0.1);
padding: 4px 12px;
border: 1px solid rgba(0, 255, 255, 0.3);
border-radius: 12px;
font-weight: 500;
text-shadow: 0 0 5px rgba(0, 255, 255, 0.5);
}
.close-icon {
font-size: 18px;
color: #00ffff;
cursor: pointer;
transition: all 0.3s ease;
padding: 4px;
border-radius: 4px;
text-shadow: 0 0 5px rgba(0, 255, 255, 0.5);
&:hover {
background: rgba(0, 255, 255, 0.2);
transform: rotate(90deg);
box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
}
}
.test-content {
max-height: 150px;
overflow-y: auto;
padding: 12px;
scrollbar-width: none;
/* Firefox */
-ms-overflow-style: none;
/* IE and Edge */
&::-webkit-scrollbar {
display: none;
/* Chrome, Safari and Opera */
}
}
</style>

View File

@ -0,0 +1,156 @@
<template>
<div class="test-item" v-if="item.typeMasgeLx == '02'" @click="goDetail(item.id, item.typeMasgeLx)">
<div class="item-header">
<div class="item-title">{{ item.qbmc || '' }}</div>
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
</div>
<div class="item-message">{{ item.qbnr }}</div>
<div class="item-time">{{ item.xtCjsj || '' }}</div>
</div>
<div class="test-item" v-if="item.typeMasgeLx == '03'" @click="goDetail(item.id, item.typeMasgeLx)">
<div class="item-header">
<div class="item-title">{{ item.bgmc || '' }}</div>
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
</div>
<div class="item-message" v-html="item.bgnr"></div>
<div class="item-time">{{ item.xtCjsj || '' }}</div>
</div>
<div class="test-item" v-if="item.typeMasgeLx == '04'" @click="goDetail(item.id, item.typeMasgeLx)">
<div class="item-header">
<div class="item-title">{{ item.zlbt || '' }}</div>
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
</div>
<div class="item-message" v-html="item.zlnr"></div>
<div class="item-time">{{ item.xtCjsj || '' }}</div>
</div>
<div class="test-item" v-if="item.typeMasgeLx == '05'" @click="goDetail(item.id, item.typeMasgeLx)">
<div class="item-header">
<div class="item-title">{{ item.zlbt || '' }}</div>
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
</div>
<div class="item-message" v-html="item.zlnr"></div>
<div class="item-time">{{ item.xtCjsj || '' }}</div>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const props = defineProps({
item: {
type: Object,
default: () => ({})
}
})
const informationMap = {
'01': '报警信息',
'02': '信息上报',
'03': '研判审批',
'04': '研判指令',
'05': '线索下发',
}
const emit=defineEmits(['goDetail'])
const goDetail = (id, lx) => {
let path = ''
switch (lx) {
case '02':
path = '/InfoCollection'
break;
case '03':
path = '/strategicResearchs'
break;
default:
case '04':
path = '/judgmentCommand'
break;
case '05':
path = '/InstructionInformation'
break;
}
router.push({
path: path,
query: {
id: id
}
})
}
</script>
<style lang="scss" scoped>
.test-item {
background: rgba(10, 59, 109, 0.8);
border: 1px solid rgba(0, 255, 255, 0.3);
border-radius: 8px;
padding: 12px;
margin-bottom: 10px;
box-shadow: 0 2px 8px rgba(0, 255, 255, 0.2);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
gap: 8px;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 255, 255, 0.4);
border-color: rgba(0, 255, 255, 0.6);
}
&:last-child {
margin-bottom: 0;
}
}
.item-header {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
}
.item-title {
font-size: 14px;
font-weight: 500;
color: #00ffff;
flex: 0 0 60%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-shadow: 0 0 5px rgba(0, 255, 255, 0.5);
}
.item-type {
font-size: 12px;
font-weight: bold;
color: #00ffff;
background: linear-gradient(135deg, #00ffff 0%, #00aaff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
flex: 1;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-shadow: 0 0 5px rgba(0, 255, 255, 0.7);
}
.item-message {
font-size: 14px;
color: #cceeff;
line-height: 1.5;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-word;
margin: 4px 0;
}
.item-time {
font-size: 12px;
color: #66ccff;
text-align: right;
margin-top: 4px;
text-shadow: 0 0 3px rgba(0, 255, 255, 0.3);
}
</style>

View File

@ -595,6 +595,11 @@ const sendMessage = (gzlid) => {
qcckPost(promes, '/mosty-gsxt/gsxt/bqbk/sendFqzl ').then(res => { qcckPost(promes, '/mosty-gsxt/gsxt/bqbk/sendFqzl ').then(res => {
console.log(res); console.log(res);
}) })
break;
case 'QBSP':
qcckPost(promes, '/mosty-gsxt/qbcj/callback ').then(res => {
console.log(res);
})
break; break;
} }
} }

View File

@ -64,7 +64,6 @@ const startDrag = (e) => {
// 处理移动 // 处理移动
const handleMove = (e) => { const handleMove = (e) => {
if (!isDragging.value) return; if (!isDragging.value) return;
let clientX, clientY; let clientX, clientY;
if (e.type === 'mousemove') { if (e.type === 'mousemove') {
clientX = e.clientX; clientX = e.clientX;

View File

@ -133,7 +133,6 @@ onBeforeUnmount(() => {
}); });
// 带样式的下载方法 // 带样式的下载方法
const downloadWithStyles = () => { const downloadWithStyles = () => {
const wordDocument = ` const wordDocument = `
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >
<head> <head>

View File

@ -11,6 +11,7 @@
<AppMain /> <AppMain />
</div> </div>
</div> </div>
<TestDiv />
</div> </div>
</template> </template>
@ -20,6 +21,7 @@ import NavBar from "./components/NavBar";
import SideBar from "./components/SideBar/index"; import SideBar from "./components/SideBar/index";
import AppMain from "./components/AppMain"; import AppMain from "./components/AppMain";
import TagsView from "./components/TagsView"; import TagsView from "./components/TagsView";
import TestDiv from "@/components/common/TestDiv.vue";
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,9 +1,6 @@
import * as ElIcons from "@element-plus/icons-vue"; import * as ElIcons from "@element-plus/icons-vue";
import Axios from 'axios' import Axios from 'axios'
import { createApp } from "vue";
import {
createApp
} from "vue";
import App from "./App.vue"; import App from "./App.vue";
import router from "./router"; import router from "./router";
import store from "./store"; import store from "./store";

View File

@ -1,5 +1,5 @@
// let url = "ws://80.155.0.82:8006/mosty-api/mosty-websocket/socket/"; //线上 // let url = "ws://80.155.0.82:8006/mosty-api/mosty-websocket/socket/"; //线上
let url = "ws://155.240.22.30:2109/mosty-api/mosty-websocket/socket/"; //线上 let url = "wss://sg.lz.dsj.xz/websocket/mosty-websocket/socket/"; //线上
if(process.env.NODE_ENV === 'development') { if(process.env.NODE_ENV === 'development') {
url = "ws://47.108.232.77:9537/mosty-api/mosty-websocket/socket/"; //本地 url = "ws://47.108.232.77:9537/mosty-api/mosty-websocket/socket/"; //本地

View File

@ -15,9 +15,7 @@ import store from "@/store";
* 私有路由表 * 私有路由表
*/ */
export const privateRoutes = [ export const privateRoutes = [];
];
/** /**
* 公开路由表 * 公开路由表
@ -65,6 +63,10 @@ export const publicRoutes = [
path: "/information", path: "/information",
name: "information", name: "information",
component: () => import("@/views/backOfficeSystem/JudgmentHome/internalAuditor/information.vue"), component: () => import("@/views/backOfficeSystem/JudgmentHome/internalAuditor/information.vue"),
}, {
path: "/Spdloyment",
name: "Spdloyment",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/auditList/components/spdloyment.vue"),
}, },
// 线索 // 线索
{ {
@ -72,6 +74,11 @@ export const publicRoutes = [
name: "clueVerification", name: "clueVerification",
component: () => import("@/views/backOfficeSystem/ApprovalInformation/Clue/index.vue"), component: () => import("@/views/backOfficeSystem/ApprovalInformation/Clue/index.vue"),
}, },
{
path: "/ReviewListSH",
name: "ReviewListSH",
component: () => import("@/views/backOfficeSystem/JudgmentHome/ReviewList/detail.vue"),
},
// 重点人发掘 // 重点人发掘
{ {
path: "/focusExploration", path: "/focusExploration",
@ -157,7 +164,7 @@ export const publicRoutes = [
{ {
path: "/YjData", path: "/YjData",
name: "YjData", name: "YjData",
meta: { title: "预警", icon: "article-create" }, meta: { title: "预警列表", icon: "article-create" },
component: () => import("@/views/backOfficeSystem/fourColorManage/YjData/index.vue"), component: () => import("@/views/backOfficeSystem/fourColorManage/YjData/index.vue"),
}, },
// { // {
@ -356,12 +363,7 @@ export const publicRoutes = [
// component: () => import("@/views/backOfficeSystem/HumanIntelligence/FollowLeads/index"), // component: () => import("@/views/backOfficeSystem/HumanIntelligence/FollowLeads/index"),
// meta: { title: "转线索列表", icon: "article-create" }, // meta: { title: "转线索列表", icon: "article-create" },
// }, // },
{
path: "/socialInformationCrculatec",
name: "recombinantSynthesis",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/ConversionSynthesis/index"),
meta: { title: "转合成列表", icon: "article-create" },
},
// { // {
// path: "/CollectPoints", // path: "/CollectPoints",
// name: "CollectPoints", // name: "CollectPoints",
@ -371,21 +373,13 @@ export const publicRoutes = [
// icon: "article-create" // icon: "article-create"
// } // }
// }, // },
{
path: "/transferConsultationList",
name: "transferConsultationList",
component: () => import("@/views/backOfficeSystem/transferConsultationList/index.vue"),
meta: {
title: "转会商列表",
icon: "article-create"
}
},
{ {
path: "/supplementReportList", path: "/supplementReportList",
name: "supplementReportList", name: "supplementReportList",
component: () => import("@/views/backOfficeSystem/supplementReportList/index.vue"), component: () => import("@/views/backOfficeSystem/supplementReportList/index.vue"),
meta: { meta: {
title: "补充/续报列表", title: "补充续报",
icon: "article-create" icon: "article-create"
} }
}, },
@ -398,15 +392,15 @@ export const publicRoutes = [
icon: "article-create" icon: "article-create"
} }
}, },
{ // {
path: "/InformationReporting", // path: "/InformationReporting",
name: "InformationReporting", // name: "InformationReporting",
component: () => import("@/views/backOfficeSystem/InformationReporting/index.vue"), // component: () => import("@/views/backOfficeSystem/InformationReporting/index.vue"),
meta: { // meta: {
title: "蜂群信息上报", // title: "蜂群信息",
icon: "article-create" // icon: "article-create"
} // }
}, // },
// { // {
// path: "/MakeAcomment", // path: "/MakeAcomment",
// name: "MakeAcomment", // name: "MakeAcomment",
@ -504,7 +498,7 @@ export const publicRoutes = [
name: "dataReduction", name: "dataReduction",
component: () => import("@/views/backOfficeSystem/JudgmentHome/dataReduction/index"), component: () => import("@/views/backOfficeSystem/JudgmentHome/dataReduction/index"),
meta: { meta: {
title: "数据整理", title: "研判约稿",
icon: "article-create" icon: "article-create"
} }
}, },
@ -519,20 +513,20 @@ export const publicRoutes = [
// }, // },
// 后面写的研判 // 后面写的研判
{ {
path: "/tacticalResearch", path: "/strategicResearchs",
name: "tacticalResearch", name: "strategicResearchs",
component: () => import("@/views/backOfficeSystem/JudgmentHome/tacticalResearch/index.vue"), component: () => import("@/views/backOfficeSystem/JudgmentHome/strategicResearch/index.vue"),
meta: { meta: {
title: "战术研判", title: "研判报告",
icon: "article-create" icon: "article-create"
} }
}, },
{ {
path: "/strategicResearch", path: "/ReviewList",
name: "strategicResearch", name: "ReviewList",
component: () => import("@/views/backOfficeSystem/JudgmentHome/strategicResearch/index.vue"), component: () => import("@/views/backOfficeSystem/JudgmentHome/ReviewList/index.vue"),
meta: { meta: {
title: "战略研判", title: "审核列表",
icon: "article-create" icon: "article-create"
} }
}, },
@ -597,46 +591,66 @@ export const publicRoutes = [
name: "mpvPeo", name: "mpvPeo",
component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvPeo/index"), component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvPeo/index"),
meta: { meta: {
title: "重点人管理", title: "重点人员库",
icon: "article-create" icon: "article-create"
} }
}, },
{ {
path: "/mpvPeoSh", path: "/gzPeo",
name: "mpvPeoSh", name: "gzPeo",
component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvPeoSh/index"), component: () => import("@/views/backOfficeSystem/DeploymentDisposal/gzPeo/index"),
meta: { meta: {
title: "重点人审批", title: "关注人员库",
icon: "article-create" icon: "article-create"
} }
}, },
{ {
path: "/mpvGroup", path: "/mpvGroup",
name: "mpvGroup", name: "mpvGroup",
component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvGroup/index"), component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvGroup/index"),
meta: { meta: {
title: "重点群体管理", title: "重点群体",
icon: "article-create"
}
},
{
path: "/mpvGroupSh",
name: "mpvGroupSh",
component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvGroupSh/index"),
meta: {
title: "重点群体审核",
icon: "article-create" icon: "article-create"
} }
}, },
{ {
path: "/mpvCar", path: "/mpvCar",
name: "mpvCar", name: "mpvCar",
component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvCar/index"), component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvCar/index"),
meta: { meta: {
title: "重点车辆管理", title: "重点车辆",
icon: "article-create" icon: "article-create"
} }
}, },
{
path: "/mvpSP",
name: "mvpSP",
component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mvpSP/index"),
meta: {
title: "审核列表",
icon: "article-create"
}
},
// {
// path: "/mpvPeoSh",
// name: "mpvPeoSh",
// component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvPeoSh/index"),
// meta: {
// title: "重点人审批",
// icon: "article-create"
// }
// },
// {
// path: "/mpvGroupSh",
// name: "mpvGroupSh",
// component: () => import("@/views/backOfficeSystem/DeploymentDisposal/mpvGroupSh/index"),
// meta: {
// title: "重点群体审核",
// icon: "article-create"
// }
// },
] ]
}, },
{ {
@ -717,14 +731,24 @@ export const publicRoutes = [
// }, // },
{ {
path: "/JobAppraisal", path: "/permissionApply",
name: "JobAppraisal", name: "permissionApply",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/JobAppraisal/index"), component: () => import("@/views/backOfficeSystem/HumanIntelligence/permissionApply/index"),
meta: { meta: {
title: "工作考核", title: "权限申请",
icon: "article-create" icon: "article-create"
} }
}, },
{
path: "/appraisalManagement",
name: "appraisalManagement",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/appraisalManagement/index"),
meta: {
title: "考核管理",
icon: "article-create"
}
},
{ {
path: "/FileData", path: "/FileData",
name: "FileData", name: "FileData",
@ -975,6 +999,21 @@ export const publicRoutes = [
icon: "article-ranking" icon: "article-ranking"
}, },
children: [ children: [
{
path: "/socialInformationCrculatec",
name: "recombinantSynthesis",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/ConversionSynthesis/index"),
meta: { title: "转合成列表", icon: "article-create" },
},
{
path: "/transferConsultationList",
name: "transferConsultationList",
component: () => import("@/views/backOfficeSystem/transferConsultationList/index.vue"),
meta: {
title: "转会商列表",
icon: "article-create"
}
},
{ {
path: "/DatAcquisition", path: "/DatAcquisition",
name: "DatAcquisition", name: "DatAcquisition",
@ -1112,8 +1151,52 @@ export const publicRoutes = [
title: "重点人员落地审核", title: "重点人员落地审核",
icon: "article-create" icon: "article-create"
} }
}, {
path: "/tacticalResearch",
name: "tacticalResearch",
component: () => import("@/views/backOfficeSystem/JudgmentHome/tacticalResearch/index.vue"),
meta: {
title: "战术研判",
icon: "article-create"
}
},
{
path: "/strategicResearch",
name: "strategicResearch",
component: () => import("@/views/backOfficeSystem/JudgmentHome/strategicResearch/index.vue"),
meta: {
title: "战略研判",
icon: "article-create"
}
}, },
] ]
}, {
path: "/tacticalResearch",
name: "tacticalResearch",
component: () => import("@/views/backOfficeSystem/JudgmentHome/tacticalResearch/index.vue"),
meta: {
title: "战术研判",
icon: "article-create"
}
},
{
path: "/strategicResearch",
name: "strategicResearch",
component: () => import("@/views/backOfficeSystem/JudgmentHome/strategicResearch/index.vue"),
meta: {
title: "战略研判",
icon: "article-create"
}
},
{
path: "/JobAppraisal",
name: "JobAppraisal",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/JobAppraisal/index"),
meta: {
title: "工作考核",
icon: "article-create"
}
}, },
// { // {
// path: "/ResearchHome", // path: "/ResearchHome",

View File

@ -44,9 +44,11 @@ service.interceptors.response.use(
const { success, code, msg, message, data, model } = response.data; const { success, code, msg, message, data, model } = response.data;
// 需要判断当前请求是否成功 // 需要判断当前请求是否成功
if (success && code === 10000) { if (success && code === 10000) {
return data ? data : response.data; // 成功后返回解析后的数据 return data || [null,0,undefined,''].includes(data) ? data : response.data; // 成功后返回解析后的数据
// return data ? data : response.data; // // 成功后返回解析后的数据
} else if (code === 200 || code == "00000" || code == "10000" || msg == 'success' || model || response.data.success == true) { } else if (code === 200 || code == "00000" || code == "10000" || msg == 'success' || model || response.data.success == true) {
return data ? data : response.data; // // 成功后返回解析后的数据 return data || [null,0,undefined,''].includes(data) ? data : response.data; // 成功后返回解析后的数据
// return data ? data : response.data; // // 成功后返回解析后的数据
} else if (code === 401) { } else if (code === 401) {
store.dispatch('user/logout'); store.dispatch('user/logout');
ElMessage.error(message); // 提示错误信息 ElMessage.error(message); // 提示错误信息

View File

@ -7,11 +7,22 @@ const getChildrenRoutes = (routes) => {
const result = []; const result = [];
const { deptBizType, deptLevel } = getItem('deptId')[0] const { deptBizType, deptLevel } = getItem('deptId')[0]
const roleList = getItem('roleList') ? getItem('roleList').filter(item => item.roleCode == 'JS_666666').length > 0 : false const roleList = getItem('roleList') ? getItem('roleList').filter(item => item.roleCode == 'JS_666666').length > 0 : false
const xjLsit = getItem('roleList') ? getItem('roleList').filter(item => item.roleCode == 'JS_999999').length > 0 : false
console.log(roleList, xjLsit);
routes.forEach((route) => { routes.forEach((route) => {
if (route.children && route.children.length > 0) { if (route.children && route.children.length > 0) {
if (deptBizType == '23' && roleList) { if (deptBizType == '23') {
// 在这个条件分支中也需要过滤掉/internalAuditor路由
if (roleList) {
result.push(...route.children); result.push(...route.children);
} else if (xjLsit) {
if (route.path == '/JudgmentHome') {
route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
result.push(...route.children);
} else {
result.push(...route.children);
}
} else { } else {
if (route.path == '/HumanIntelligence') { if (route.path == '/HumanIntelligence') {
route.children.splice(route.children.findIndex(item => item.path == '/auditList'), 1) route.children.splice(route.children.findIndex(item => item.path == '/auditList'), 1)
@ -19,7 +30,6 @@ const getChildrenRoutes = (routes) => {
} else { } else {
result.push(...route.children); result.push(...route.children);
} }
if (route.path == '/JudgmentHome') { if (route.path == '/JudgmentHome') {
route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1) route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
result.push(...route.children); result.push(...route.children);
@ -27,6 +37,37 @@ const getChildrenRoutes = (routes) => {
result.push(...route.children); result.push(...route.children);
} }
} }
} else {
if (route.path == '/HumanIntelligence') {
route.children.splice(route.children.findIndex(item => item.path == '/auditList'), 1)
result.push(...route.children);
} else {
result.push(...route.children);
}
if (route.path == '/JudgmentHome') {
route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
result.push(...route.children);
} else {
result.push(...route.children);
}
}
// if (deptBizType == '23' && (roleList || xjLsit)) {
// // 在这个条件分支中也需要过滤掉/internalAuditor路由
// result.push(...route.children);
// } else {
// if (route.path == '/JudgmentHome' && xjLsit) {
// route.children.splice(route.children.findIndex(item => item.path == '/internalAuditor'), 1)
// result.push(...route.children);
// } else {
// result.push(...route.children);
// }
// }
} }
}); });
return result; return result;

View File

@ -143,7 +143,6 @@ const connectSSEWithPost = (prompt, options = {}) => {
reject(error); reject(error);
} }
}; };
readStream(); readStream();
}).catch(error => { }).catch(error => {
console.error('SSE请求错误:', error); console.error('SSE请求错误:', error);

View File

@ -1,5 +1,5 @@
// let url = "ws://89.40.9.89:2109/mosty-api/mosty-websocket/socket/"; //线上 // let url = "ws://89.40.9.89:2109/mosty-api/mosty-websocket/socket/"; //线上
let url = "ws://155.240.22.30:2109/mosty-api/mosty-websocket/socket/"; //线上 let url = "ws://89.40.9.93:50039/mosty-websocket/socket/"; //线上
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
url = "ws://47.108.232.77:9537/mosty-api/mosty-websocket/socket/"; //本地 url = "ws://47.108.232.77:9537/mosty-api/mosty-websocket/socket/"; //本地
@ -86,8 +86,6 @@ class WebSoketClass {
if (fun) fun(true); if (fun) fun(true);
}; };
this.ws.onclose = (e) => { this.ws.onclose = (e) => {
console.log(e);
console.log('WebSocket连接已关闭关闭码:', e.code, '原因:', e.reason); console.log('WebSocket连接已关闭关闭码:', e.code, '原因:', e.reason);
// 如果是正常关闭(1000)或手动关闭(1001),不进行重连 // 如果是正常关闭(1000)或手动关闭(1001),不进行重连
if (e.code !== 1000 && e.code !== 1001) { if (e.code !== 1000 && e.code !== 1001) {
@ -165,7 +163,6 @@ class WebSoketClass {
// 接收发送消息 // 接收发送消息
getMessage() { getMessage() {
this.ws.onmessage = (e) => { this.ws.onmessage = (e) => {
console.log(e);
try { try {
if (e.data) { if (e.data) {
@ -175,6 +172,9 @@ class WebSoketClass {
// 触发音频播放 // 触发音频播放
console.log('触发音频播放'); console.log('触发音频播放');
emitter.emit('openYp', newsDate.data); // 传递消息数据 emitter.emit('openYp', newsDate.data); // 传递消息数据
} else {
emitter.emit('webSocketMessage', { data: newsDate.data, type: newsDate.type });
} }
// else if (newsDate.type === 'ALARM_STOP' || newsDate.type === 'warning_stop') { // else if (newsDate.type === 'ALARM_STOP' || newsDate.type === 'warning_stop') {
// // 触发音频停止 // // 触发音频停止
@ -187,7 +187,7 @@ class WebSoketClass {
// emitter.emit('statusUpdate', newsDate.data); // emitter.emit('statusUpdate', newsDate.data);
// } // }
// // 通用消息事件 // // 通用消息事件
// emitter.emit('webSocketMessage', newsDate);
} }
} catch (error) { } catch (error) {
console.error('处理WebSocket消息失败:', error); console.error('处理WebSocket消息失败:', error);

View File

@ -36,14 +36,10 @@
<div class="grid-item flex just-between" style="" v-for="(item, index) in srcList" :key="index"> <div class="grid-item flex just-between" style="" v-for="(item, index) in srcList" :key="index">
<div class="names">{{ item.name }}</div> <div class="names">{{ item.name }}</div>
<div class="icon"><a :href="setAddress(item.id)" download><el-icon><Download /></el-icon></a></div> <div class="icon"><a :href="setAddress(item.id)" download><el-icon><Download /></el-icon></a></div>
</div> </div>
</div> </div>
</el-card> </el-card>
</div> </div>
</template> </template>
<script setup> <script setup>
@ -116,7 +112,6 @@ const route = useRoute()
onMounted(() => { onMounted(() => {
const id = route.query.id const id = route.query.id
getDataById(id) getDataById(id)
}) })
// const onSubmit = async (val) => { // const onSubmit = async (val) => {
// const data = [] // const data = []

View File

@ -18,7 +18,7 @@ import ZdqtPage from "./components/zdqtPage.vue";
import ZdclPage from "./components/zdclPage.vue"; import ZdclPage from "./components/zdclPage.vue";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const tabBtn=ref(["重点人","重点群体","重点车辆"]) const tabBtn=ref(["重点人","重点群体","重点车辆"])
const tabActive=ref(0) const tabActive=ref(0)
onMounted(() => { onMounted(() => {

View File

@ -0,0 +1,70 @@
<template>
<!-- 添加 -->
<el-dialog :model-value="modelValue" :title="title" width="40%" :before-close="handleClose">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules">
</FormMessage>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="submitForm">确认</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { defineProps, defineEmits, ref, watch, reactive, getCurrentInstance } from 'vue'
import FormMessage from "@/components/aboutTable/FormMessage.vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
data: {
type: Object,
default: () => { }
},
modelValue: {
type: Boolean,
default: false
},
title: {
type: String,
default: '案件信息'
},
dict: {
type: Object,
default: () => { }
}
})
const emit = defineEmits(['update:modelValue', 'comfirm'])
const listQuery = ref({})
const formData = ref([
{ label: "案件名称", prop: "ajmc", type: "input", width: '100%' },
{ label: "案件时间", prop: "sasj", type: "date", width: '100%' },
{ label: "案件编码", prop: "ajbm", type: "input", width: '100%' },
])
const rules = reactive({
ajmc: [{ required: true, message: "请输入案件名称", trigger: "blur" }],
sasj: [{ required: true, message: "请输入案件时间", trigger: "change" }],
ajbm: [{ required: true, message: "请输入案件编码", trigger: "blur" }],
})
const elform=ref(null)
const submitForm = () => {
elform.value.submit((val) => {
if (val) {
emit('comfirm', val)
handleClose()
}
})
}
watch(
() => props.data,
(val) => {
listQuery.value = val ? { ...val } : {}
},
{ deep: true }
)
// 取消:关闭弹窗
const handleClose = () => {
listQuery.value = {}
emit('update:modelValue', false)
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,86 @@
<template>
<!-- 添加 -->
<el-dialog :model-value="modelValue" :title="title" width="40%" :before-close="handleClose">
<el-form ref="historyForm" style="max-width: 600px" :model="diaLogRuleForm" :rules="rules">
<el-form-item label-width="160px" label="姓名" prop="ryXm" style="width: 100%;">
<el-input v-model="diaLogRuleForm.ryXm" :placeholder="`请输入联系人姓名`" />
</el-form-item>
<el-form-item label-width="160px" label="人员身份证号" prop="rySfzh" style="width: 100%;">
<el-input v-model="diaLogRuleForm.rySfzh" :placeholder="`请输入人员身份证号`" />
</el-form-item>
<el-form-item label-width="160px" label="对应关系" prop="dygx" style="width: 100%;">
<el-select v-model="diaLogRuleForm.dygx" placeholder="请选择对应关系">
<el-option v-for="item in dict.D_BZ_QSGXDM" :key="item.dm" :label="item.zdmc" :value="item.dm" />
</el-select>
</el-form-item>
<el-form-item label-width="160px" label="联系人电话" prop="lxrDh" style="width: 100%;">
<el-input v-model="diaLogRuleForm.lxrDh" :placeholder="`请输入联系人电话`" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="onSubmit">
确认
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { defineProps, defineEmits, ref, watch, reactive } from 'vue'
import { generateRandom10Digits } from '@/utils/tools'
const props = defineProps({
data: {
type: Object,
default: () => { }
},
modelValue: {
type: Boolean,
default: false
},
title: {
type: String,
default: ''
},
dict: {
type: Object,
default: () => { }
}
})
const historyForm = ref(null)
const emit = defineEmits(['update:modelValue', 'submit'])
const diaLogRuleForm = ref({})
const rules = reactive({
ryXm: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
rySfzh: [{ required: true, message: '请输入身份证号', trigger: 'blur' }],
dygx: [{ required: true, message: '请选择对应关系', trigger: 'change' }],
})
watch(
() => props.data,
(val) => {
diaLogRuleForm.value = val ? { ...val } : {}
},
{ deep: true }
)
// 取消:关闭弹窗
const handleClose = () => {
diaLogRuleForm.value = {}
emit('update:modelValue', false)
}
// 提交
const onSubmit = () => {
historyForm.value.validate().then((valid) => {
if (valid) {
emit('submit', { ...diaLogRuleForm.value }) // 提交数据
handleClose()
}
}).catch((err) => {
console.log(err);
});
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,91 @@
<template>
<!-- 添加 -->
<el-dialog :model-value="modelValue" :title="title" width="40%" :before-close="handleClose">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules">
<template #zfmjXm>
<el-input v-model="listQuery.zfmjXm" :placeholder="`请输入民警姓名`" readonly @click="changeShow" />
</template>
</FormMessage>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="submitForm">确认</el-button>
</template>
</el-dialog>
<ChooseUser :Single="true" v-model="chooseMarksVisible" @choosedUsers="addMarks" :roleIds="roleIds" />
</template>
<script setup>
import { defineProps, defineEmits, ref, watch, reactive, getCurrentInstance } from 'vue'
import { generateRandom10Digits } from '@/utils/tools'
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
const { proxy } = getCurrentInstance();
const { D_ZFNR_MBLX } = proxy.$dict("D_ZFNR_MBLX")
const props = defineProps({
data: {
type: Object,
default: () => { }
},
modelValue: {
type: Boolean,
default: false
},
title: {
type: String,
default: '走访信息'
},
dict: {
type: Object,
default: () => { }
}
})
const emit = defineEmits(['update:modelValue', 'comfirm'])
const historyForm = ref(null)
const chooseMarksVisible = ref(false)
const listQuery = ref({})
const formData = ref([
{ label: "民警姓名", prop: "zfmjXm", type: "slot", width: '100%' },
{ label: "走访时间", prop: "zfsj", type: "date", width: '100%' },
{ label: "走访地址", prop: "zfdz", type: "input", width: '100%' },
{ label: "走访方式", prop: "zffs", type: "input", width: '100%' },
{ label: "走访情况", prop: "zfqk", type: "textarea", width: '100%' },
])
const rules = reactive({
zfmjXm: [{ required: true, message: "请选择民警姓名", trigger: "blur" }],
zfsj: [{ required: true, message: "请输入走访时间", trigger: "change" }],
zfdz: [{ required: true, message: "请输入走访地址", trigger: "blur" }],
zffs: [{ required: true, message: "请输入走访方式", trigger: "blur" }],
zfqk: [{ required: true, message: "请输入走访情况", trigger: "blur" }],
})
const changeShow = () => {
chooseMarksVisible.value = true
}
const addMarks = (val) => {
listQuery.value.zfmjXm = val[0].userName
listQuery.value.zfmjSfzh=val[0].idEntityCard
}
const elform=ref(null)
const submitForm = () => {
elform.value.submit((val) => {
if (val) {
emit('comfirm', val)
handleClose()
}
})
}
watch(
() => props.data,
(val) => {
console.log(val);
listQuery.value = val ? { ...val } : {}
},
{ deep: true }
)
// 取消:关闭弹窗
const handleClose = () => {
listQuery.value = {}
emit('update:modelValue', false)
}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,306 @@
<template>
<el-dialog :title="titleValue" width="800px" :model-value="modelValue" append-to-body @close="closed">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules">
<template #rrry>
<el-input v-model="listQuery.rrry" :placeholder="`请输入民警姓名`" readonly @click="changeShow" />
</template>
<template #fjxx>
<!-- 文件列表区域 -->
<div class="file-attachment-section">
<div class="section-title">相关附件</div>
<div class="file-list-container">
<div v-if="listQuery.fileList.length === 0" class="empty-file-list">暂无附件</div>
<div v-else class="file-list">
<div v-for="(file, index) in listQuery.fileList" :key="index" class="file-item">
<div class="file-info">
<span class="file-name">{{ file.originalName }}</span>
<span class="file-time">{{ file.uploadTime }}</span>
</div>
<div class="file-actions">
<el-button type="text" size="small" @click="downloadFile(file)" title="下载文件" :disabled="disabled">
<el-icon>
<Download />
</el-icon>
</el-button>
<el-button type="text" size="small" @click="deleteFile(index)" title="删除文件" class="delete-btn"
:disabled="disabled">
<el-icon>
<Delete />
</el-icon>
</el-button>
</div>
</div>
</div>
</div>
<!-- 上传按钮区域 -->
<div class="upload-btn-container">
<el-upload v-model:file-list="listQuery.fileList" class="upload-demo" :show-file-list="false" multiple
:http-request="handleUploadRequest" :on-remove="handleRemove" :limit="3" :on-exceed="handleExceed">
<el-button type="primary" :disabled="disabled">上传文件</el-button>
</el-upload>
</div>
</div>
</template>
</FormMessage>
<template #footer>
<div class="dialog-footer">
<el-button @click="closed">取消</el-button>
<el-button type="primary" @click="onComfirm">确认</el-button>
</div>
</template>
</el-dialog>
<ChooseUser :Single="true" v-model="chooseMarksVisible" @choosedUsers="addMarks" :roleIds="roleIds" />
</template>
<script setup>
import { ref, onMounted, reactive, watch, getCurrentInstance } from "vue";
import { generateRandom10Digits } from '@/utils/tools'
import { uploadMultipleFiles } from '@/views/backOfficeSystem/DeploymentDisposal/mpvGroup/model/fileUp.js'
import { ElMessage } from 'element-plus';
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
const { proxy } = getCurrentInstance()
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
titleValue: {
type: String,
default: "现实表现"
},
data: {
type: Object,
default: () => { }
}
});
const emits = defineEmits(["update:modelValue", "comfirm"]);
const formData = ref([
{ label: "录入人员", prop: "rrry", type: "slot", width: '100%' },
{ label: "录入时间", prop: "lrsj", type: "date", width: '100%' },
{ label: "表现内容", prop: "bxnr", type: "textarea", width: '100%' },
{ label: "附件信息", prop: "fjxx", type: "slot", width: '100%' },
])
const rules = reactive({
rrry: [{ required: true, message: "请选择民警姓名", trigger: "blur" }],
lrsj: [{ required: true, message: "请输入录入时间", trigger: "change" }],
bxnr: [{ required: true, message: "请输入表现内容", trigger: "blur" }],
})
const listQuery = ref({fileList:[]})
const roleIds=ref([])
const chooseMarksVisible=ref(false)
const changeShow = () => {
chooseMarksVisible.value = true
}
const addMarks = (val) => {
listQuery.value.rrry = val[0].userName
roleIds.value = val.map(item => item.id)
}
const closed = () => {
listQuery.value={}
listQuery.value.fileList = []
emits("update:modelValue", false);
};
const onComfirm = () => {
emits("comfirm", {...listQuery.value,fjxx:listQuery.value.fileList.length>0?JSON.stringify(listQuery.value.fileList):null });
emits("update:modelValue", false);
}
watch(() => props.data, (val) => {
if (val) {
listQuery.value={...val,fileList:val.fjxx}
}
},{deep: true})
// 下载文件
const downloadFile = (file) => {
// 实际项目中这里应该调用下载API
console.log('下载文件:', file.name)
// 示例window.open(file.url)
}
// 删除文件
const deleteFile = (index) => {
// 实际项目中这里应该先调用删除API成功后再从列表中移除
listQuery.value.fileList.splice(index, 1)
ElMessage.success('文件已删除')
}
// 上传相关方法
const handleUploadRequest = async (options) => {
try {
// 调用uploadMultipleFiles进行文件上传
const result = await uploadMultipleFiles(options.file, {
uploadedFiles: listQuery.value.fileList,
fjIds: [], // 如果需要保存文件ID列表可以在这里传递
compressImage: null // 可选的图片压缩函数
});
// 更新文件列表,添加上传时间信息
const index = listQuery.value.fileList.findIndex(f => f.originalName === options.file.name);
if (index !== -1) {
listQuery.value.fileList[index].uploadTime = new Date().toLocaleString('zh-CN');
}
// 调用成功回调
if (options.onSuccess) {
options.onSuccess(result);
}
} catch (error) {
console.error('文件上传失败:', error);
// 调用失败回调
if (options.onError) {
options.onError(error);
}
}
}
const handleRemove = (uploadFile, uploadFiles) => {
// 实际项目中这里应该先调用删除API成功后再从列表中移除
const index = listQuery.value.fileList.findIndex(f => f.name === uploadFile.name);
if (index !== -1) {
listQuery.value.fileList.splice(index, 1);
}
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
@import "@/assets/css/element-plus.scss";
</style>
<style>
.tabBoxRadio .el-checkbox__inner {
border-radius: 50% !important;
}
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
display: none;
}
.file-attachment-section {
margin-top: 15px;
width: 100%;
}
.section-title {
font-size: 14px;
font-weight: 500;
color: #303133;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #ebeef5;
}
.file-list-container {
max-height: 100px;
overflow-y: auto;
border: 1px solid #ebeef5;
border-radius: 4px;
background-color: #ffffff;
margin-bottom: 10px;
}
/* 自定义滚动条样式 */
.file-list-container::-webkit-scrollbar {
width: 6px;
}
.file-list-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
.file-list-container::-webkit-scrollbar-thumb {
background: #c0c4cc;
border-radius: 3px;
}
.file-list-container::-webkit-scrollbar-thumb:hover {
background: #909399;
}
.empty-file-list {
padding: 20px;
text-align: center;
color: #909399;
font-size: 12px;
}
.file-list {
padding: 5px;
}
.file-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 10px;
margin-bottom: 2px;
background-color: #f8f9fa;
border-radius: 4px;
transition: all 0.3s ease;
cursor: pointer;
}
.file-item:hover {
background-color: #e6f7ff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.file-info {
flex: 1;
display: flex;
align-items: center;
gap: 15px;
min-width: 0;
}
.file-name {
flex: 1;
font-size: 12px;
color: #303133;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.file-size {
font-size: 11px;
color: #909399;
min-width: 60px;
}
.file-time {
font-size: 11px;
color: #909399;
}
.file-actions {
display: flex;
align-items: center;
gap: 5px;
margin-left: 10px;
}
.file-actions .el-button {
padding: 0 5px;
margin: 0;
color: #606266;
transition: color 0.3s ease;
}
.file-actions .el-button:hover {
color: #409eff;
}
.delete-btn:hover {
color: #f56c6c !important;
}
.upload-btn-container {
display: flex;
justify-content: center;
margin-top: 10px;
}
</style>

View File

@ -0,0 +1,242 @@
<template>
<el-dialog :title="titleValue" width="800px" :model-value="modelValue" append-to-body @close="closed">
<el-form ref="historyForm" style="max-width: 600px" :model="ruleForm" :rules="rules" label-width="auto">
<el-form-item label="车牌号" prop="cph">
<el-input v-model="ruleForm.cph" placeholder="请输入车牌号" />
</el-form-item>
<el-form-item label="车辆识别码" prop="clsbm">
<el-input v-model="ruleForm.clsbm" placeholder="请输入车辆识别码" />
</el-form-item>
<el-form-item label="车辆型号" prop="cllx">
<el-select v-model="ruleForm.cllx" placeholder="请选择车辆型号">
<el-option :label="item.zdmc" :value="item.dm" v-for="(item, index) in dict.D_BZ_CLLX"
:key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item label="车辆颜色" prop="clys">
<el-select v-model="ruleForm.clys" placeholder="请选择车辆颜色">
<el-option :label="item.zdmc" :value="item.dm" v-for="(item, index) in dict.D_BZ_CLYS"
:key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item label="车辆品牌" prop="clpp">
<el-select v-model="ruleForm.clpp" placeholder="请选择车辆品牌">
<el-option :label="item.zdmc" :value="item.dm" v-for="(item, index) in dict.D_BZ_CLPP"
:key="index"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="closed">取消</el-button>
<el-button type="primary" @click="onComfirm()">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, onMounted, reactive, watch, getCurrentInstance } from "vue";
import { generateRandom10Digits } from '@/utils/tools'
const { proxy } = getCurrentInstance()
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
titleValue: {
type: String,
default: "关联车辆"
},
data: {
type: Object,
default: () => { }
}, dict: {
type: Object,
default: () => { }
}
});
const emits = defineEmits(["update:modelValue", "comfirm"]);
const historyForm = ref(null)
const ruleForm = ref({})
const rules = reactive({
cph: [
{ required: true, message: '请输入车牌号', trigger: 'blur' },
],
});
const onComfirm = () => {
historyForm.value.validate((valid, fields) => {
if (valid) {
const promes = {
...ruleForm.value,
id: ruleForm.value.id ? ruleForm.value.id : generateRandom10Digits(),
}
emits("comfirm", { ...promes });
closed()
} else {
console.log('error submit!', fields)
}
})
}
watch(() => props.modelValue, (val) => {
ruleForm.value = props.data
}, { deep: true })
const closed = () => {
ruleForm.value = {}
emits("update:modelValue", false);
};
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
@import "@/assets/css/element-plus.scss";
.tabBoxRadio .el-checkbox__inner {
border-radius: 50% !important;
}
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
display: none;
}
.file-attachment-section {
margin-top: 15px;
}
.section-title {
font-size: 14px;
font-weight: 500;
color: #303133;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #ebeef5;
}
.file-list-container {
max-height: 100px;
overflow-y: auto;
border: 1px solid #ebeef5;
border-radius: 4px;
background-color: #ffffff;
margin-bottom: 10px;
}
/* 自定义滚动条样式 */
.file-list-container::-webkit-scrollbar {
width: 6px;
}
.file-list-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
.file-list-container::-webkit-scrollbar-thumb {
background: #c0c4cc;
border-radius: 3px;
}
.file-list-container::-webkit-scrollbar-thumb:hover {
background: #909399;
}
.empty-file-list {
padding: 20px;
text-align: center;
color: #909399;
font-size: 12px;
}
.file-list {
padding: 5px;
}
.file-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 10px;
margin-bottom: 2px;
background-color: #f8f9fa;
border-radius: 4px;
transition: all 0.3s ease;
cursor: pointer;
}
.file-item:hover {
background-color: #e6f7ff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.file-info {
flex: 1;
display: flex;
align-items: center;
gap: 15px;
min-width: 0;
}
.file-name {
flex: 1;
font-size: 12px;
color: #303133;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.file-size {
font-size: 11px;
color: #909399;
min-width: 60px;
}
.file-time {
font-size: 11px;
color: #909399;
}
.file-actions {
display: flex;
align-items: center;
gap: 5px;
margin-left: 10px;
}
.file-actions .el-button {
padding: 0 5px;
margin: 0;
color: #606266;
transition: color 0.3s ease;
}
.file-actions .el-button:hover {
color: #409eff;
}
.delete-btn:hover {
color: #f56c6c !important;
}
.upload-btn-container {
display: flex;
justify-content: center;
margin-top: 10px;
}
.butHandle {
display: flex;
justify-content: space-between;
align-items: center;
}
::v-deep .el-range-input {
color: #000 !important;
}
</style>

View File

@ -0,0 +1,367 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}重点人管理</span>
<div>
<el-button type="primary" size="small" v-if="!disabled" :loading="loading" @click="submit">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" labelWidth="100px" ref="elform"
:rules="rules"></FormMessage>
<div class="ml50 mr50">
<span class="mr10">人员标签模型 : </span><el-button type="primary" v-if="!disabled"
@click="chooseMarksVisible = true">选择</el-button>
</div>
<div class="boxlist ml50 mr50">
<MyTable :tableData="listQuery.bqList" :tableColumn="tableDate.tableColumn" :key="tableDate.keyCount"
:tableConfiger="tableDate.tableConfiger" :controlsWidth="tableDate.controlsWidth">
<template #bqLb="{ row }">
<DictTag :value="row.bqLb" :tag="false" :options="props.dic.D_GS_BQ_LB" />
</template>
<template #bqLx="{ row }">
<DictTag :value="row.bqLx" :tag="false" :options="props.dic.D_GS_BQ_LX" />
</template>
<template #bqZl="{ row }">
<DictTag :value="row.bqZl" :tag="false" :options="props.dic.D_GS_BQ_ZL" />
</template>
<template #controls="{ row }">
<el-link type="danger" @click="delDictItem(row.bqId)">删除</el-link>
</template>
</MyTable>
</div>
<!-- 选择审核人 -->
<div class="ww100 mt20 ml50 mr50">
<el-steps direction="vertical" :active="listQuery.wccz" space="500" finish-status="success">
<el-step title="发起申请">
<template #description>
<div class="flex align-center ww100 mt10 mb20">
<el-input v-model="listQuery.sqrXm" readonly class="ww20"></el-input>
<el-input v-model="listQuery.sqrSsbmmc" readonly class="ww20 ml10 mr10"></el-input>
<span class="f12" style="color: #333333">
备注发起人和部门根据登陆人自动填写</span>
</div>
</template>
</el-step>
<el-step title="审核确认">
<template #description>
<div class="flex align-center ww100 mt10 mb20 depBox">
<span class="mr4">审核部门 : </span>
<MOSTY.Department :isAll="true" @getDepValue="getShdep" v-model="listQuery.shSsbmdm" clearable :placeholder="listQuery.shSsbmmc ? listQuery.shSsbmmc : ''" />
</div>
</template>
</el-step>
<el-step title="审批确认">
<template #description>
<div class="flex align-center ww100 mt10 mb20 depBox">
<span lass="mr4">审批部门 : </span>
<MOSTY.Department :isAll="true" @getDepValue="getSPdep" v-model="listQuery.spSsbmdm" clearable :placeholder="listQuery.spSsbmmc ? listQuery.spSsbmmc : ''" />
</div>
</template>
</el-step>
</el-steps>
</div>
</div>
</div>
<ChooseMarks v-model="chooseMarksVisible" @choosed="choosed" :roleIds="roleIds" />
</template>
<script setup>
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { getItem } from "@/utils/storage";
import ChooseMarks from "@/components/ChooseList/ChooseMarks/index.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
import {
ref,
defineExpose,
reactive,
onMounted,
defineEmits,
getCurrentInstance,
watch
} from "vue";
const emit = defineEmits(["updateDate"]);
const props = defineProps({
dic: Object
});
const { proxy } = getCurrentInstance();
const roleIds = ref([]);
const chooseMarksVisible = ref(false);
const dialogForm = ref(false); //弹窗
const pcsList = ref([]);
const rules = reactive({
ryXm: [{ required: true, message: "请输入姓名", trigger: "blur" }],
...rule.identityCardRule({ validator: true },'rySfzh'), //身份证校验
...rule.phoneRule({ validator: true }, "ryLxdh"), // 是否必填 是否进行校验,
rySfzh: [{ required: true, message: "请输入身份证号", trigger: "blur" }],
ryLxdh: [{ required: true, message: "请输入联系电话", trigger: "blur" }],
ryXb: [{ required: true, message: "请选择性别", trigger: "change" }],
ryMz: [{ required: true, message: "请选择民族", trigger: "change" }],
ryCsrq: [{ required: true, message: "请选择出生日期", trigger: "change" }],
ryJg: [{ required: true, message: "请选择籍贯", trigger: "change" }],
zdrRyjb: [{ required: true, message: "请选择人员级别", trigger: "change" }],
zdrYjdj: [{ required: true, message: "请选择预警等级", trigger: "change" }]
});
const listQuery = ref({}); //表单
const formData = ref([]);
watch(() => props.dic,(val) => {
formData.value = [
{ label: "姓名", prop: "ryXm", type: "input" },
{
label: "性别",
prop: "ryXb",
type: "select",
options: props.dic.D_BZ_XB
},
{
label: "民族",
prop: "ryMz",
type: "select",
options: props.dic.D_BZ_MZ
},
{ label: "身份证号", prop: "rySfzh", type: "input" },
{ label: "联系电话", prop: "ryLxdh", type: "input" },
{ label: "出生日期", prop: "ryCsrq", type: "date" },
{
label: "籍贯",
prop: "ryJg",
type: "select",
options: props.dic.D_BZ_XZQHDM
},
{
label: "人员级别",
prop: "zdrRyjb",
type: "select",
options: props.dic.D_GS_ZDR_RYJB
},
{
label: "预警等级",
prop: "zdrYjdj",
type: "select",
options: props.dic.D_GS_ZDR_YJDJ
},
{
label: "户籍地区划",
prop: "hjdQh",
type: "select",
options: props.dic.D_BZ_XZQHDM
},
{ label: "户籍地详址", prop: "hjdXz", type: "input" },
{
label: "户籍地派出所",
prop: "hjdPcsdm",
type: "select",
options: pcsList
},
{
label: "现住地区划",
prop: "xzdQh",
type: "select",
options: props.dic.D_BZ_XZQHDM
},
{ label: "现住地详址", prop: "xzdXz", type: "input" },
{
label: "现住地派出所",
prop: "xzdPcsdm",
type: "select",
options: pcsList
},
{ label: "管辖单位", prop: "gxSsbmdm",depMc:'gxSsbmmc', type: "department" },
{ label: "诉求单位", prop: "sqSsbmdm",depMc:'sqSsbmmc', type: "department" },
{ label: "责任单位", prop: "zrSsbmdm",depMc:'zrSsbmmc', type: "department" },
{
label: "所属警种",
prop: "zdrSsjz",
type: "select",
options: props.dic.D_GS_BK_SSJZ
},
{
label: "涉及警种",
prop: "zdrSjjz",
type: "select",
options: props.dic.D_GS_BK_SSJZ,
multiple: true
},
{ label: "管控民警姓名", prop: "gkMjXm", type: "input" },
{ label: "管控民警警号", prop: "gkMjJh", type: "input" },
{ label: "管控原因", prop: "zdrLkyy", type: "textarea", width: "100%" },
{
label: "处置状态",
prop: "zdrCzzt",
type: "select",
options: props.dic.D_GS_ZDR_CZZT
},
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime" },
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime" }
];
},
{ immediate: true, deep: true }
);
const tableDate = reactive({
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
controlsWidth: 90, //操作栏宽度
keyCount: 0,
tableColumn: [
{ label: "标签名称", prop: "bqMc" },
{ label: "标签代码", prop: "bqDm" },
{ label: "标签种类", prop: "bqZl", showSolt: true },
{ label: "标签类型", prop: "bqLx", showSolt: true },
{ label: "标签类别", prop: "bqLb", showSolt: true }
]
});
const loading = ref(false);
const elform = ref();
const title = ref("");
const showInfo = ref(false);
const disabled = ref(false);
onMounted(() => {
chooseDep();
});
const chooseDep = () => {
qcckPost({ orgLevel: 40 }, "/mosty-base/deptFeign/queryListByDept").then(
(res) => {
pcsList.value = res.map((item) => {
return { zdmc: item.orgName, dm: item.orgCode, value: item.orgCode };
});
}
);
};
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = type == "add" ? "新增" : type == "detail" ? "详情" : "编辑";
disabled.value = type == "detail" ? true : false;
tableDate.tableConfiger.haveControls = type == "detail" ? false : true;
if (type == "add") {
listQuery.value.sqrXm = getItem("USERNAME");
listQuery.value.bkfqrSfzh = getItem("idEntityCard");
listQuery.value.sqrSsbmmc = getItem("deptId")[0].deptName;
listQuery.value.sqrSsbmdm = getItem("deptId")[0].deptCode;
}
setTimeout(() => {
showInfo.value = true;
}, 5);
if (row) getDataById(row.id);
};
// 根据id查询详情
const getDataById = (id) => {
qcckGet({}, "/mosty-gsxt/tbGsxtZdry/selectVoById/" + id).then((res) => {
listQuery.value = res;
listQuery.value.zdrSjjz = listQuery.value.zdrSjjz.split(",");
tableDate.bqList = res.bqList;
listQuery.value.sqrXm = getItem("USERNAME");
listQuery.value.bkfqrSfzh = getItem("idEntityCard");
listQuery.value.sqrSsbmmc = getItem("deptId")[0].deptName;
listQuery.value.sqrSsbmdm = getItem("deptId")[0].deptCode;
});
};
// 选择标签
const choosed = (val) => {
listQuery.value.bqList = val.map((v) => {
return { bqZl: v.bqLb, bqId: v.id, bqLx: v.bqLx, bqLb: v.bqLb, bqMc: v.bqMc, bqDm: v.bqDm };
});
roleIds.value = val.map((v) => v.id);
};
// 删除
const delDictItem = (bqId) => {
listQuery.value.bqList = listQuery.value.bqList.filter((v) => v.bqId != bqId);
tableDate.keyCount++;
};
// 提交
const submit = () => {
elform.value.submit((data) => {
data.zdrSjjz = data.zdrSjjz.join(",");
let url = title.value == "新增" ? "/mosty-gsxt/tbGsxtZdry/save" : "/mosty-gsxt/tbGsxtZdry/update";
let params = { ...data };
if (params.hjdPcsdm) {
let obj = pcsList.value.find((v) => v.dm == params.hjdPcsdm);
params.hjdPcsmc = obj ? obj.zdmc : "";
}
if (params.xzdPcsdm) {
let obj1 = pcsList.value.map((v) => v.dm == params.xzdPcsdm);
params.xzdPcsmc = obj1 ? obj1.zdmc : "";
}
loading.value = true;
qcckPost(params, url).then(() => {
loading.value = false;
proxy.$message({ type: "success", message: title.value + "成功" });
emit("updateDate");
close();
}).catch(() => {
loading.value = false;
});
});
};
const getShdep = (val) =>{
listQuery.value.shSsbmmc = val ? val.orgName : ''
}
const getSPdep = (val) =>{
listQuery.value.spSsbmmc = val ? val.orgName : ''
}
// 关闭
const close = () => {
listQuery.value = {};
dialogForm.value = false;
loading.value = false;
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
.boxlist {
width: calc(99% - 50px);
margin-top: 10px;
overflow: hidden;
}
.depBox {
border: 1px solid #e9e9e9;
width: 305px;
padding: 0 0 0 4px;
border-radius: 4px;
::v-deep .el-input__inner {
border: none;
}
::v-deep .el-cascader .el-input.is-focus .el-input__inner {
border-color: transparent !important;
}
::v-deep .el-input__inner:focus {
box-shadow: none;
}
::v-deep .el-input.is-disabled .el-input__inner {
border-color: transparent !important;
}
}
</style>

View File

@ -0,0 +1,228 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">流线索</span>
<div>
<el-button type="primary" :loading="loading" @click="submit">保存</el-button>
<el-button @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
<template #gapdive>
<div style="width: 100%; height: 10px" class="mb20">
<el-divider content-position="left">基础信息</el-divider>
</div>
</template>
<template #gapline>
<div style="width: 100%; height: 10px" class="mb20">
<el-divider content-position="left">线索内容</el-divider>
</div>
</template>
<template #scfj>
<div style="width: 100%; padding-left: 50px">
<div>
上传附件:<span class="f12">可附电子表格Word文档图像音视频文件</span>
</div>
<div>
<MOSTY.Upload :showBtn="true" :limit="10" v-model="fjdz" />
</div>
</div>
</template>
</FormMessage>
<el-divider content-position="left"><span class="mr20">相关人员</span>
</el-divider>
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" :tableHeight="pageForm.tableHeight"
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
<template #xb="{ row }">
<DictTag :value="row.xb" :tag="false" :options="props.dic.D_BZ_XB" />
</template>
<template #bqList="{ row }">
<div v-if="row.bqList">
<el-tag type="success" v-for="(it, idx) in row.bqList" :key="idx">{{
it.bqMc
}}</el-tag>
</div>
</template>
</MyTable>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qcckPost } from "@/api/qcckApi.js";
import {
ref,
defineExpose,
reactive,
onMounted,
defineEmits,
getCurrentInstance,
nextTick
} from "vue";
const emit = defineEmits(["change"]);
const props = defineProps({
dic: Object
});
const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗
const rules = reactive({
xsMc: [{ required: true, message: "请输入线索名称", trigger: "blur" }],
xlLx: [{ required: true, message: "请选择线索类型", trigger: "change" }],
qbLy: [{ required: true, message: "请选择情报来源", trigger: "change" }]
});
const formData = ref([
{ prop: "gapdive", type: "slot", width: "100%" },
{ label: "线索名称", prop: "xsMc", type: "input" },
{
label: "线索类型",
prop: "xlLx",
type: "select",
options: props.dic.D_GS_XS_LX
},
{
label: "情报来源",
prop: "qbLy",
type: "select",
options: props.dic.D_GS_XS_LY
},
{ label: "指向开始时间", prop: "zxkssj", type: "datetime" },
{ label: "指向结束时间", prop: "zxjssj", type: "datetime" },
{ label: "指向地点", prop: "zxdz", type: "input" },
{
label: "所属专题",
prop: "sszt",
type: "select",
options: props.dic.D_BZ_SSZT
},
{ prop: "gapline", type: "slot", width: "100%" },
{ prop: "scfj", type: "slot", width: "100%" },
{ label: "线索内容", prop: "xsNr", type: "textarea", width: "100%" },
{
label: "群体类型",
prop: "qtlx",
type: "select",
options: props.dic.D_GS_XS_QTLX
},
{ label: "群体名称", prop: "qtmc", type: "input" },
{ label: "涉及人数", prop: "sjrs", type: "inputNumber" },
{ label: "线索报送单位", prop: "ssbmdm", type: "department" }
]);
const fjdz = ref();
const listQuery = ref({}); //表单
const loading = ref(false);
const elform = ref();
const pageForm = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false,
haveControls: false
},
controlsWidth: 220,
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "性别", prop: "xb", showSolt: true },
{ label: "身份证号", prop: "sfzh" },
{ label: "户籍地", prop: "hjdz" },
{ label: "户籍地派出所", prop: "hjdpcs" },
{ label: "标签", prop: "bqList", showSolt: true }
]
});
onMounted(() => {
tabHeightFn();
});
// 初始化数据
const init = (list) => {
fjdz.value = [];
tabHeightFn();
dialogForm.value = true;
pageForm.tableData = list.map((it) => {
return {
xm: it.ryXm,
xb: it.ryXb,
sfzh: it.rySfzh,
hjdz: it.xzdXz,
hjdpcs: it.hjdPcsmc,
hjdpcsdm: it.hjdPcsdm,
bqList: it.bqList || []
};
});
pageForm.keyCount++;
};
// 提交
const submit = () => {
elform.value.submit((data) => {
let params = { ...data, ryList: pageForm.tableData, cjLx: "0" };
params.fjdz = fjdz.value.length > 0 ? fjdz.value.join(",") : "";
loading.value = true;
qcckPost(params, "/mosty-gsxt/qbcj/add")
.then((res) => {
loading.value = false;
proxy.$message({ type: "success", message: "成功" });
emit("change");
close();
})
.catch(() => {
loading.value = false;
});
});
};
// 关闭
const close = () => {
fjdz.value = [];
listQuery.value = {};
dialogForm.value = false;
loading.value = false;
};
// 表格高度计算
const tabHeightFn = () => {
pageForm.tableHeight = window.innerHeight - 720;
window.onresize = function () {
tabHeightFn();
};
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
.boxlist {
width: 99%;
height: 225px;
margin-top: 10px;
overflow: hidden;
}
::v-deep .avatar-uploader {
display: flex;
align-items: center;
}
::v-deep .el-upload-list {
margin-left: 20px;
display: flex;
align-items: center;
}
::v-deep .el-upload-list__item-name .el-icon {
top: 3px;
}
</style>

View File

@ -0,0 +1,526 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}关注人管理</span>
<div>
<el-button type="primary" size="small" v-if="butShow" :loading="loading" @click="submit">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt flex just-between">
<div class="left_box">
<ul class="anchor-list">
<li @click="scrollToSection('info-section')" :class="activeSection === 'info-section' ? 'active' : ''">人员信息
</li>
<li @click="scrollToSection('backinfo-section')"
:class="activeSection === 'backinfo-section' ? 'active' : ''">人员标签</li>
<li @click="scrollToSection('groupLabels-section')"
:class="activeSection === 'groupLabels-section' ? 'active' : ''" v-if="!butShow">关联车辆</li>
<li @click="scrollToSection('character-section')"
:class="activeSection === 'character-section' ? 'active' : ''">背景信息</li>
<li @click="scrollToSection('controlInfo-section')"
:class="activeSection === 'controlInfo-section' ? 'active' : ''" v-if="!butShow">管控信息</li>
<li @click="scrollToSection('featinfo-section')"
:class="activeSection === 'featinfo-section' ? 'active' : ''" v-if="!butShow">全要素布控</li>
<li @click="scrollToSection('demandsInfo-section')"
:class="activeSection === 'demandsInfo-section' ? 'active' : ''" v-if="!butShow">密切联系人</li>
<li @click="scrollToSection('requestInfo-section')"
:class="activeSection === 'requestInfo-section' ? 'active' : ''" v-if="!butShow">动态轨迹</li>
<li @click="scrollToSection('personnel-section')"
:class="activeSection === 'personnel-section' ? 'active' : ''" v-if="!butShow">行为信息</li>
<li @click="scrollToSection('judgmentRecord-section')"
:class="activeSection === 'judgmentRecord-section' ? 'active' : ''" v-if="!butShow">走访记录</li>
<li @click="scrollToSection('historyAssembly-section')"
:class="activeSection === 'historyAssembly-section' ? 'active' : ''" v-if="!butShow">案件信息</li>
<li @click="scrollToSection('joblogging-section')"
:class="activeSection === 'joblogging-section' ? 'active' : ''" v-if="!butShow">现实表现</li>
<li @click="scrollToSection('joblogging-joblog')"
:class="activeSection === 'joblogging-joblog' ? 'active' : ''" v-if="!butShow">操作日志</li>
</ul>
</div>
<div class="right_box" ref="rightBox">
<div id="info-section">
<Info ref="info" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="backinfo-section">
<PersonnelTags ref="personnelTags" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="groupLabels-section" v-if="!butShow">
<Vehicle ref="vehicle" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="character-section">
<BackInfo ref="backInfo" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="controlInfo-section" v-if="!butShow">
<ControlInfo ref="controlInfo" title="重点人" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="featinfo-section" v-if="!butShow">
<Deployment ref="deployment" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="demandsInfo-section" v-if="!butShow">
<Contact ref="contact" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="requestInfo-section" v-if="!butShow">
<DynamicTrajectory ref="dynamicTrajectory" :disabled="disabled" :showBut="showBut" />
</div>
<div id="personnel-section" v-if="!butShow">
<BehaviorInfo ref="behaviorInfo" :disabled="disabled" :showBut="showBut" />
</div>
<div id="judgmentRecord-section" v-if="!butShow">
<VisitRecord ref="visitRecord" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="historyAssembly-section" v-if="!butShow" >
<CaseInfo ref="caseInfo" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="joblogging-section" v-if="!butShow">
<ActualPerformance ref="actualPerformance" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
<div id="joblogging-joblog" v-if="!butShow" >
<CzModel ref="czModel" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { getItem } from "@/utils/storage";
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
import { tbGsxtZdrySelectVoById, tbGsxtZdrySave } from "@/api/zdr.js";
import ControlInfo from '../../mpvGroup/model/controlInfo.vue'
import Info from "../model/info.vue";
import PersonnelTags from '../model/personnelTags.vue'
import Vehicle from '../model/vehicle.vue'
import BackInfo from '../model/bakInfo.vue'
import Deployment from '../model/deployment.vue'
import Contact from '../model/contact.vue'
import DynamicTrajectory from '../model/dynamicTrajectory.vue'
import BehaviorInfo from '../model/behaviorInfo.vue'
import VisitRecord from '../model/visitRecord.vue'
import CaseInfo from '../model/caseInfo.vue'
import ActualPerformance from '../model/actualPerformance.vue'
import CzModel from '../model/czModel.vue'
import { useRouter, useRoute } from 'vue-router'
import { ref, onUnmounted, getCurrentInstance } from "vue";
const router = useRouter()
const route = useRoute()
const { proxy } = getCurrentInstance();
const emit = defineEmits(["updateDate"]);
const chooseMarksVisible = ref(false);
const dialogForm = ref(false); //弹窗
const loading = ref(false);
const disabled = ref(false)
const showBut = ref(false)
const listQuery = ref({});
const butShow = ref(false)
const title = ref('新增')
const showData=ref(false)
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
if (type == 'add') {
butShow.value = true
title.value = '新增'
disabled.value = false
showBut.value = false
} else {
butShow.value = false
tbGsxtZdrySelectVoById({ id: row.id }).then(res => {
listQuery.value = { ...res }
})
if (type == 'edit') {
showBut.value = true
disabled.value = false
title.value = '编辑'
} else if (type == "del") {
disabled.value = true
showBut.value = false
title.value = '删除'
}
else {
disabled.value = true
showBut.value = false
title.value = '详情'
}
}
};
const activeSection = ref('info-section')
const rightBox = ref(null)
// 滚动到指定区域
const scrollToSection = (sectionId) => {
const element = document.getElementById(sectionId);
if (element && rightBox.value) {
// 计算需要滚动的距离
const elementTop = element.offsetTop;
rightBox.value.scrollTo({
top: elementTop - 150, // 减去一些偏移量,让内容更好看
behavior: 'smooth' // 平滑滚动
});
activeSection.value = sectionId;
}
}
// 监听滚动,更新当前激活的锚点
const handleScroll = () => {
if (!rightBox.value) return;
const scrollPosition = rightBox.value.scrollTop + 50;
const sections = [
'info-section', 'backinfo-section', 'groupLabels-section',
'character-section', 'controlInfo-section', 'featinfo-section',
'demandsInfo-section', 'requestInfo-section', 'personnel-section',
'judgmentRecord-section', 'historyAssembly-section', 'joblogging-section', "czModel-section"
];
for (let i = sections.length - 1; i >= 0; i--) {
const section = document.getElementById(sections[i]);
if (section && section.offsetTop <= scrollPosition) {
activeSection.value = sections[i];
break;
}
}
}
// 监听右侧区域的滚动事件
if (typeof window !== 'undefined') {
window.addEventListener('load', () => {
if (rightBox.value) {
rightBox.value.addEventListener('scroll', handleScroll);
}
});
// 组件卸载时移除事件监听
onUnmounted(() => {
if (rightBox.value) {
rightBox.value.removeEventListener('scroll', handleScroll);
}
});
}
const info = ref()
const personnelTags = ref()
// 提交
const submit = async () => {
// 使用Promise.all处理所有子组件的验证和数据获取
const [infoData, personnelTagsData] = await Promise.all([
info.value.throwData()
// personnelTags.value.throwData(),
]);
tbGsxtZdrySave({...infoData,rylx:'03'}).then(res => {
proxy.$message({
message: '新增成功',
type: 'success',
})
close()
})
console.log(infoData);
};
// 关闭
const close = () => {
if (route.query.id) {
const query = { ...route.query };
delete query.id;
router.replace({ query });
}
dialogForm.value = false;
loading.value = false;
emit('updateDate')
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.behaviorInfo {
margin: 0 0 10px 0;
// padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
h3 {
font-size: 18px;
font-weight: 600;
color: #303133;
}
}
.textContent {
margin-top: 10px;
}
/* 外层容器:控制尺寸和隐藏默认滚动条 */
.list-container {
width: 100%;
height: 400px;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
/* 隐藏外层滚动条,由内部控制 */
margin: 20px auto;
font-family: Arial, sans-serif;
}
/* 固定标题行 */
.list-header {
display: flex;
justify-content: space-around;
align-items: center;
background-color: #f5f5f5;
color: #333;
font-weight: 600;
padding: 0 16px;
height: 50px;
border-bottom: 2px solid #ddd;
position: sticky;
/* 关键:固定标题 */
top: 0;
z-index: 10;
/* 确保在最上层 */
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
/* 可滚动内容区域 */
.list-body {
height: calc(100% - 50px);
/* 容器高度减去标题高度 */
overflow-y: auto;
/* 垂直滚动 */
overflow-x: hidden;
background-color: #fff;
}
/* 每一行内容 */
.list-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 16px;
height: 50px;
border-bottom: 1px dashed #eee;
font-size: 14px;
color: #555;
}
.list-item:hover {
background-color: #f9f9f9;
}
/* 自定义滚动条(可选) */
.list-container::-webkit-scrollbar {
width: 8px;
}
.list-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
.list-container::-webkit-scrollbar-thumb {
background: #999;
border-radius: 4px;
}
.list-container::-webkit-scrollbar-thumb:hover {
background: #666;
}
/* Firefox 支持 */
.list-container {
scrollbar-width: thin;
scrollbar-color: #999 #f1f1f1;
}
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
#contact-section {
margin-top: 20px;
}
.boxlist {
width: calc(99% - 50px);
margin-top: 10px;
overflow: hidden;
}
.depBox {
border: 1px solid #e9e9e9;
width: 305px;
padding: 0 0 0 4px;
border-radius: 4px;
::v-deep .el-input__inner {
border: none;
}
::v-deep .el-cascader .el-input.is-focus .el-input__inner {
border-color: transparent !important;
}
::v-deep .el-input__inner:focus {
box-shadow: none;
}
::v-deep .el-input.is-disabled .el-input__inner {
border-color: transparent !important;
}
}
.left_box {
width: 220px;
background-color: #fafafa;
border: 1px solid #ebeef5;
border-radius: 6px;
padding: 15px;
transition: all 0.3s ease;
}
.left_box:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
border-color: #409eff;
}
// 锚点列表样式
.anchor-list {
list-style: none;
padding: 0;
margin: 0;
}
.anchor-list li {
padding: 10px 15px;
margin-bottom: 5px;
cursor: pointer;
border-radius: 4px;
transition: all 0.3s ease;
font-size: 14px;
color: #606266;
position: relative;
}
.anchor-list li:hover {
background-color: #e6f7ff;
color: #409eff;
}
.anchor-list li.active {
background-color: #409eff;
color: #ffffff;
font-weight: 500;
}
.anchor-list li.active::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background-color: #ffffff;
border-radius: 0 2px 2px 0;
}
.right_box {
width: calc(100% - 240px);
overflow-y: auto;
// padding: 15px;
background-color: #ffffff;
// border: 1px solid #ebeef5;
border-radius: 6px;
.right_box>div {
background-color: #f8f9fa;
border-radius: 6px;
padding: 20px;
transition: all 0.3s ease;
margin-bottom: 10px;
}
.right_box>div:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.right_box h3 {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
}
.right_box h3::after {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 60px;
height: 2px;
background-color: #409eff;
}
.headline {
font-size: 16px;
font-weight: 500;
color: #303133;
margin-bottom: 15px;
}
// 按钮样式优化
.el-button {
margin-left: 8px;
transition: all 0.3s ease;
}
.el-button:first-child {
margin-left: 0;
}
}
// 响应式设计
@media screen and (max-width: 768px) {
.form_cnt {
flex-direction: column;
}
.left_box {
width: 100%;
margin-bottom: 20px;
}
.right_box {
width: 100%;
}
.anchor-list {
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.anchor-list li {
flex: 1 1 calc(33.333% - 10px);
margin-bottom: 5px;
text-align: center;
padding: 8px 5px;
font-size: 12px;
}
}
::v-deep .avatar-uploader {
display: flex
}
</style>

View File

@ -0,0 +1,228 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">流线索</span>
<div>
<el-button type="primary" :loading="loading" @click="submit">保存</el-button>
<el-button @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
<template #gapdive>
<div style="width: 100%; height: 10px" class="mb20">
<el-divider content-position="left">基础信息</el-divider>
</div>
</template>
<template #gapline>
<div style="width: 100%; height: 10px" class="mb20">
<el-divider content-position="left">线索内容</el-divider>
</div>
</template>
<template #scfj>
<div style="width: 100%; padding-left: 50px">
<div>
上传附件:<span class="f12">可附电子表格Word文档图像音视频文件</span>
</div>
<div>
<MOSTY.Upload :showBtn="true" :limit="10" v-model="fjdz" />
</div>
</div>
</template>
</FormMessage>
<el-divider content-position="left"><span class="mr20">相关人员</span>
</el-divider>
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" :tableHeight="pageForm.tableHeight"
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
<template #xb="{ row }">
<DictTag :value="row.xb" :tag="false" :options="props.dic.D_BZ_XB" />
</template>
<template #bqList="{ row }">
<div v-if="row.bqList">
<el-tag type="success" v-for="(it, idx) in row.bqList" :key="idx">{{
it.bqMc
}}</el-tag>
</div>
</template>
</MyTable>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qcckPost } from "@/api/qcckApi.js";
import {
ref,
defineExpose,
reactive,
onMounted,
defineEmits,
getCurrentInstance,
nextTick
} from "vue";
const emit = defineEmits(["change"]);
const props = defineProps({
dic: Object
});
const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗
const rules = reactive({
xsMc: [{ required: true, message: "请输入线索名称", trigger: "blur" }],
xlLx: [{ required: true, message: "请选择线索类型", trigger: "change" }],
qbLy: [{ required: true, message: "请选择情报来源", trigger: "change" }]
});
const formData = ref([
{ prop: "gapdive", type: "slot", width: "100%" },
{ label: "线索名称", prop: "xsMc", type: "input" },
{
label: "线索类型",
prop: "xlLx",
type: "select",
options: props.dic.D_GS_XS_LX
},
{
label: "情报来源",
prop: "qbLy",
type: "select",
options: props.dic.D_GS_XS_LY
},
{ label: "指向开始时间", prop: "zxkssj", type: "datetime" },
{ label: "指向结束时间", prop: "zxjssj", type: "datetime" },
{ label: "指向地点", prop: "zxdz", type: "input" },
{
label: "所属专题",
prop: "sszt",
type: "select",
options: props.dic.D_BZ_SSZT
},
{ prop: "gapline", type: "slot", width: "100%" },
{ prop: "scfj", type: "slot", width: "100%" },
{ label: "线索内容", prop: "xsNr", type: "textarea", width: "100%" },
{
label: "群体类型",
prop: "qtlx",
type: "select",
options: props.dic.D_GS_XS_QTLX
},
{ label: "群体名称", prop: "qtmc", type: "input" },
{ label: "涉及人数", prop: "sjrs", type: "inputNumber" },
{ label: "线索报送单位", prop: "ssbmdm", type: "department" }
]);
const fjdz = ref();
const listQuery = ref({}); //表单
const loading = ref(false);
const elform = ref();
const pageForm = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false,
haveControls: false
},
controlsWidth: 220,
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "性别", prop: "xb", showSolt: true },
{ label: "身份证号", prop: "sfzh" },
{ label: "户籍地", prop: "hjdz" },
{ label: "户籍地派出所", prop: "hjdpcs" },
{ label: "标签", prop: "bqList", showSolt: true }
]
});
onMounted(() => {
tabHeightFn();
});
// 初始化数据
const init = (list) => {
fjdz.value = [];
tabHeightFn();
dialogForm.value = true;
pageForm.tableData = list.map((it) => {
return {
xm: it.ryXm,
xb: it.ryXb,
sfzh: it.rySfzh,
hjdz: it.xzdXz,
hjdpcs: it.hjdPcsmc,
hjdpcsdm: it.hjdPcsdm,
bqList: it.bqList || []
};
});
pageForm.keyCount++;
};
// 提交
const submit = () => {
elform.value.submit((data) => {
let params = { ...data, ryList: pageForm.tableData, cjLx: "0" };
params.fjdz = fjdz.value.length > 0 ? fjdz.value.join(",") : "";
loading.value = true;
qcckPost(params, "/mosty-gsxt/qbcj/add")
.then((res) => {
loading.value = false;
proxy.$message({ type: "success", message: "成功" });
emit("change");
close();
})
.catch(() => {
loading.value = false;
});
});
};
// 关闭
const close = () => {
fjdz.value = [];
listQuery.value = {};
dialogForm.value = false;
loading.value = false;
};
// 表格高度计算
const tabHeightFn = () => {
pageForm.tableHeight = window.innerHeight - 720;
window.onresize = function () {
tabHeightFn();
};
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
.boxlist {
width: 99%;
height: 225px;
margin-top: 10px;
overflow: hidden;
}
::v-deep .avatar-uploader {
display: flex;
align-items: center;
}
::v-deep .el-upload-list {
margin-left: 20px;
display: flex;
align-items: center;
}
::v-deep .el-upload-list__item-name .el-icon {
top: 3px;
}
</style>

View File

@ -0,0 +1,351 @@
<template>
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left>
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
</template>
<div class="flex just-center">
<el-button size="small" type="primary" v-for="it in D_GS_BK_SQLX" :key="it.dm"
@click="handleApplication(it)">{{ it.zdmc }}</el-button>
</div>
</el-popover> -->
<!-- <el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click">
<template #reference>
<el-button size="small" type="primary" @click="(visiblefp = !visiblefp), (visible = false)">指定分配</el-button>
</template>
<div>
<el-input readonly v-model="obj.fpmc" @click="chooseUserVisible = true" placeholder="请选择民警"></el-input>
<div class="flex just-center mt10">
<el-button @click="(visiblefp = false), (obj = {})" size="small">取消</el-button>
<el-button type="primary" @click="handlefp" size="small">分配</el-button>
</div>
</div>
</el-popover> -->
<!-- <el-button size="small" type="primary" @click="handleZxs">转线索</el-button> -->
<!-- <el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
<!-- <el-button size="small" type="primary">导入</el-button> -->
<el-button type="primary" size="small" @click="addEdit('add', '')">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">新增</span>
</el-button>
</template>
</PageTitle>
<!-- 表格 -->
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@chooseData="chooseData">
<template #bqList="{ row }">
<ul>
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
item.bqFz || 0 }} ) </li>
</ul>
</template>
<template #ryXb="{ row }">
<DictTag :tag="false" :value="row.ryXb" :options="D_BZ_XB" />
</template>
<template #ryJg="{ row }">
<DictTag :tag="false" :value="row.ryJg" :options="D_BZ_XZQHDM" />
</template>
<template #ryMz="{ row }">
<DictTag :tag="false" :value="row.ryMz" :options="D_BZ_MZ" />
</template>
<template #hjdQh="{ row }">
<DictTag :tag="false" :value="row.hjdQh" :options="D_BZ_XZQHDM" />
</template>
<template #zdrRyjb="{ row }">
<DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB" />
</template>
<template #zdrBkZt="{ row }">
<DictTag :tag="false" :value="row.zdrBkZt" :options="D_ZDRGK_GKZT" />
</template>
<template #zdrCzzt="{ row }">
<DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" />
</template>
<template #zdrZt="{ row }">
<DictTag :tag="false" :value="row.zdrZt" :options="D_GS_ZDQT_ZT" />
</template>
<template #xtSjzt="{ row }">
<div> {{ row.xtSjzt == 0 ? "注销" : row.xtSjzt == 1 ? "正常" : "封存" }}</div>
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link size="small" type="success" @click="handleremove(row.id)">移除</el-link>
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
@click="handleSend(row.id)">送审</el-link>
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
@click="addEdit('edit', row)">编辑</el-link>
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div>
<!-- 详情 -->
<AddForm ref="addFormDiloag" @updateDate="getList"
:dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" />
<!-- 选择用户 -->
<ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" />
<!-- 转线索 -->
<ZxsForm v-if="showzxs" ref="zxsDilof" @change="getList"
:dic="{ D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX }"></ZxsForm>
</div>
</template>
<script setup>
import { ElMessage } from "element-plus";
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
import ZxsForm from "./components/zxsForm.vue";
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import AddForm from "./components/addForm.vue";
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
const { proxy } = getCurrentInstance();
const { D_ZDRGK_GKZT,D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
proxy.$dict('D_ZDRGK_GKZT',"D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
const obj = ref({});
const showzxs = ref(false);
const zxsDilof = ref();
const show = ref(false);
const addFormDiloag = ref();
const searchBox = ref(); //搜索框
const chooseUserVisible = ref(false); //审批流程
const ids = ref([]);
const choosList = ref([]);
const visible = ref(false);
const visiblefp = ref(false);
const searchConfiger = ref([
{
label: "姓名",
prop: "ryXm",
placeholder: "请输入姓名",
showType: "input"
},
{
label: "身份证",
prop: "rySfzh",
placeholder: "请输入身份证",
showType: "input"
},
{
label: "户籍地",
prop: "hjdXz",
placeholder: "请输入户籍地",
showType: "input"
},
{
label: "人员级别",
prop: "zdrRyjb",
placeholder: "请输入人员级别",
showType: "select",
options: D_GS_ZDR_RYJB
},
]);
const queryFrom = ref({});
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "checkBox",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
},
controlsWidth: 250,
tableColumn: [
{ label: "姓名", prop: "ryXm",width: 100 },
{ label: "性别", prop: "ryXb", showSolt: true, width: 80 },
{ label: "身份证", prop: "rySfzh", width: 170 },
{ label: "民族", prop: "ryMz", showSolt: true, width: 80 },
{ label: "户籍派出所", prop: "hjdPcsmc" },
{ label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true },
{ label: "管辖单位", prop: "gxSsbmmc" },
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true,showSolt: true, width: 100 },
{ label: "审核状态", prop: "zdrZt", showSolt: true, width: 100 },
{ label: "入库时间", prop: "zdrRkkssj", },
]
});
onMounted(() => {
tabHeightFn();
if (route.query.id) {
addEdit('x', {
id: route.query.id
})
}else{
getList();
}
});
// 搜索
const onSearch = (val) => {
queryFrom.value = { ...val };
pageData.pageConfiger.pageCurrent = 1;
getList();
};
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
// rylx: '01',
let data = {...pageData.pageConfiger, ...queryFrom.value,rylx: '03' };
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
}).catch(() => {
pageData.tableConfiger.loading = false;
});
};
//送审
const handleSend = (id) => {
proxy.$confirm("确定要送审?", "警告", { type: "warning" }).then(() => {
qcckPost({ id }, "/mosty-gsxt/tbGsxtZdry/subSh").then(() => {
proxy.$message({ type: "success", message: "送审成功" });
getList();
});
})
};
// 移除
const handleremove = (id) => {
proxy.$confirm("确定要移除此重点人员?", "警告", { type: "warning" }).then(() => {
qcckPost({ id, rylx: '02' }, "/mosty-gsxt/tbGsxtZdry/update").then(() => {
proxy.$message({ type: "success", message: "移除成功" });
getList();
});
})
}
const chooseData = (data) => {
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
choosList.value = Array.isArray(data) ? data : [];
};
// 选择申请数据数据
const handleApplication = () => {
if (ids.value.length === 0) return ElMessage.error("请先选择需要布控的重点人");
qcckPost({ ids: ids.value }, "/mosty-gsxt/tbGsxtZdry/addBksq").then(() => {
ElMessage.success("申请成功");
visible.value = false;
getList();
}).catch(() => {
ElMessage.error("布控申请失败");
});
};
const handleUserSelected = (val) => {
obj.value.fpmc = val[0].userName;
obj.value.fpid = val[0].id;
};
// 处理分配
const handlefp = () => {
if (ids.value.length === 0) return ElMessage.error("请先选择需要布控的重点人");
qcckPost({ ids: ids.value, uid: obj.value.fpid }, "/mosty-gsxt/tbGsxtZdry/addGkmj").then(() => {
ElMessage.success("分配成功");
visible.value = false;
visiblefp.value = false;
getList();
}).catch(() => {
ElMessage.error("分配失败");
});
};
// 移交管控
const handleMove = () => {
if (ids.value.length === 0) return ElMessage.error("请先选择需要移交管控的重点群体");
proxy.$confirm("是否确定移交?", "警告", { type: "warning" }).then(() => {
qcckPost({ ids: ids.value }, "/mosty-gsxt/tbGsxtZdry/addSfyj").then(() => {
ElMessage.success("移交管控成功");
getList();
}).catch(() => {
ElMessage.error("移交管控失败");
});
});
};
// 转线索
const handleZxs = () => {
if (ids.value.length === 0) return ElMessage.error("请先选择需要转线索的重点群体");
showzxs.value = true;
nextTick(() => {
zxsDilof.value.init(choosList.value);
});
};
//删除操作
const deleteRow = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
qcckDelete({}, "/mosty-gsxt/tbGsxtZdry/" + id).then((res) => {
ElMessage.success("删除成功");
getList();
});
});
};
//新增编辑
const addEdit = (type, row) => {
show.value = true;
nextTick(() => {
addFormDiloag.value.init(type, row);
})
};
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style lang="scss" scoped>
.marks {
padding: 0 4px;
white-space: nowrap;
background: #73acf1;
border-radius: 4px;
color: #fff;
}
</style>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>

View File

@ -0,0 +1,294 @@
<template>
<div>
<div class="headClass" style="">
<h3>现实表现</h3>
<el-button @click="AddPore" type="primary" v-if="showBut">新增</el-button>
</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #showSolt="{ row }">
<span v-for="(item,index) in row.fjxx" :key="index">{{ item.originalName }}<span v-if="index < row.fjxx.length - 1"></span></span>
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
<el-link type="danger" @click="updDictItem(row)">修改</el-link>
</template>
</MyTable>
</div>
<!-- <VehiclDoing v-model="JudgmentShow" @comfirm="addMarks" :data="dataModel"
:dict="{ D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP }" /> -->
<JudgmentRecord v-model="JudgmentShow" @comfirm="onComfirm" :data="dataModel" />
</template>
<script setup>
import { identityCardRule } from "@/utils/rules"
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import JudgmentRecord from "../component/judgmentRecord.vue";
import { tbGsxtZdryXsbxSaveOrUpdateXsbx,tbGsxtZdryXsbxSelectZfjl,tbGsxtZdryXsbx } from '@/api/zdr.js'
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP } = proxy.$dict("D_BZ_CLLX", "D_BZ_CLYS", "D_BZ_CLPP"); //获取字典数据
const JudgmentShow = ref(false)
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const listData = ref({})
const addUpd = ref(true)
watch(() => props.dataList, (val) => {
if (val) {
listData.value = val
gettbZdryClxxSelectPage()
}
}, { deep: true })
// 表格数据
const pageData = reactive({
tableData: [],
tableColumn: [{
prop: 'rrry',
label: '录入人员',
}, {
prop: 'lrsj',
label: '录入时间',
}, {
prop: 'bxnr',
label: '表现内容',
}, {
showSolt: true,
prop: 'fjxx',
label: '附件信息',
}],
tableHeight: '200px',
keyCount: 0,
tableConfiger: {
border: true,
stripe: true,
showHeader: true,
showIndex: true,
indexLabel: '序号',
indexWidth: 60,
align: 'center',
showOverflowTooltip: true,
haveControls: !props.disabled
},
controlsWidth: 200,
})
// 修改数据接口
const dataModel = ref()
const onComfirm = (val) => {
const params = {
...val,
zdryId: listData.value.id,
}
console.log(params);
// if (props.showBut && !props.disabled) {
// if (addUpd.value) {
tbGsxtZdryXsbxSaveOrUpdateXsbx(params).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '现实表现添加成功',
type: 'success'
})
})
// }
// else {
// tbZdryClxxUpdate(params).then(res => {
// gettbZdryClxxSelectPage()
// proxy.$message({
// message: '关联车辆修改成功',
// type: 'success'
// })
// })
// }
// } else {
// pageData.tableData.push(val)
// }
}
onMounted(() => {
})
// 删除车辆
const delDictItem = (val) => {
if (!props.disabled && props.showBut) {
ElMessageBox.confirm(
'是否删除关联车辆',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
tbGsxtZdryXsbx(val).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '表现信息删除成功',
type: 'success'
})
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
} else {
pageData.tableData = pageData.tableData.filter(v => v.id != val)
}
}
const updDictItem = (val) => {
JudgmentShow.value = true
addUpd.value = false
dataModel.value = val
}
const AddPore = () => {
JudgmentShow.value = true
addUpd.value = true
}
// 查询车辆
const gettbZdryClxxSelectPage = () => {
const promes = {
zdrid: listData.value.id
}
tbGsxtZdryXsbxSelectZfjl(promes).then(res => {
pageData.tableData = res.map(item => {
return {
...item,
fjxx: item.fjxx ? JSON.parse(item.fjxx) : []
}
})
})
}
// 抛出数据并验证标签列表不为空
const throwData = () => {
return new Promise((resolve) => {
// // 验证:确保标签列表不为空
// if (!pageData.tableData || pageData.tableData.length === 0) {
// throw new Error('请录入车辆信息');
// }
resolve(pageData.tableData);
});
}
defineExpose({
throwData
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
::v-deep(.el-form) {
display: flex;
justify-content: space-between;
}
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
}
.headClass {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 20px 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
}
.headSelect {
width: 100%;
padding: 0 16px;
background-color: #fff;
border-bottom: 1px solid #eee;
display: flex;
justify-content: end;
padding-bottom: 20px;
}
/* 移除冲突样式:不要用 justify-content */
/* 控制所有 el-form-item 高度和垂直居中 */
.form-inline :deep(.el-form-item) {
margin-bottom: 0;
height: 60px;
display: flex;
align-items: center;
}
/* ✅ 按钮区域靠右,且不换行 */
.form-inline .form-actions {
margin-left: auto;
/* 推到最右边 */
white-space: nowrap;
/* 防止按钮换行 */
}
/* 统一按钮样式,增加间距和视觉舒适度 */
.form-inline :deep(.el-button) {
height: 36px;
padding: 8px 16px;
font-size: 14px;
border-radius: 4px;
}
/* 按钮之间留出间距(除了第一个) */
.form-inline :deep(.el-button:not(:first-child)) {
margin-left: 12px;
/* 比原来的 8px 更宽松 */
}
// .headClass::after {
// content: '';
// position: absolute;
// left: 0;
// bottom: -2px;
// width: 60px;
// height: 2px;
// background-color: #409eff;
// }
h3 {
margin: 0;
}
</style>

View File

@ -0,0 +1,368 @@
<template>
<div class="backinfo-container">
<div class="headClass" style="">
<h3>背景信息</h3>
<el-button type="primary" v-if="showBut" :disabled="disabled" @click="submitForm(ruleFormRef)">保存</el-button>
</div>
<div>
<!-- 全部输入框 -->
<el-form class="record" ref="ruleFormRef" :model="ruleForm" :rules="rules">
<!-- 拘留所记录 -->
<div class="detentionFacility">
<div>拘留所记录</div>
<div>
<div v-for="(item, i) in ruleForm.detentionCenterRecords" :key="item.id" class="detentionFacilityArr">
<el-form-item :prop="'detentionCenterRecords.' + i + '.str'" :rules="rules.str">
<el-input v-model="ruleForm.detentionCenterRecords[i].str" type="textarea"
class="detentionFacilityInput" placeholder="请输入拘留所记录" />
</el-form-item>
<div style="width: 100px;" v-if="showBut">
<el-button type="primary" v-if="ruleForm.detentionCenterRecords.length != 1"
@click="decreaseRecord(i, '拘留所')"></el-button>
<el-button type="primary" @click="addRecord(i, '拘留所')"
v-if="i == ruleForm.detentionCenterRecords.length - 1">+</el-button>
</div>
</div>
</div>
</div>
<!-- 看守所记录 -->
<div class="detentionFacility">
<div>看守所记录</div>
<div>
<div v-for="(item, i) in ruleForm.prison" :key="item.id" class="detentionFacilityArr">
<el-form-item :prop="'prison.' + i + '.str'" :rules="rules.str">
<el-input v-model="ruleForm.prison[i].str" type="textarea" class="detentionFacilityInput"
placeholder="请输入拘留所记录" />
</el-form-item>
<div style="width: 100px;" v-if="showBut">
<el-button type="primary" v-if="ruleForm.prison.length != 1"
@click="decreaseRecord(i, '看守所')"></el-button>
<el-button type="primary" @click="addRecord(i, '看守所')"
v-if="i == ruleForm.prison.length - 1">+</el-button>
</div>
</div>
</div>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import { reactive, ref, watch, onMounted, getCurrentInstance } from "vue";
import { tbGsxtZdryUpdate } from '@/api/zdr.js'
const { proxy } = getCurrentInstance();
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const ruleFormRef = ref()
const ruleForm = reactive({
detentionCenterRecords: [{ id: 0, str: "" }],
prison: [{ id: 0, str: "" }],
})
// 表单校验
const rules = reactive({
// str: [
// { required: true, message: '请输入具体信息', trigger: 'blur' },
// { min: 3, max: 20, message: '请最少输入3个字,最多输入20个字', trigger: 'blur' },
// ],
})
watch(() => props.dataList, (val) => {
if (val) {
ruleForm.detentionCenterRecords = val.jlsJl && val.kssJl.length > 0 ? val.jlsJl.map((item, index) => {
return {
id: index,
str: item
}
}) : [{ id: 0, str: "" }],
ruleForm.prison = val.kssJl && val.kssJl.length > 0 ? val.kssJl.map((item, index) => {
return {
id: index,
str: item
}
}) : [{ id: 0, str: "" }]
}
}, { deep: true })
// 增加输入记录输入框
const addRecord = (val, type) => {
if (type == '拘留所') {
ruleForm.detentionCenterRecords.push({ id: val })
} else {
ruleForm.prison.push({ id: val })
}
}
// 减少输入记录输入框
const decreaseRecord = (val, type) => {
if (type == '拘留所') {
ruleForm.detentionCenterRecords.splice(val, 1)
} else {
ruleForm.prison.splice(val, 1)
}
}
//提交数据校验表单
const submitForm = async (formEl) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
const promes = {
id: props.dataList.id,
jlsJl: ruleForm.detentionCenterRecords.map(item => item.str),
kssJl: ruleForm.prison.map(item => item.str),
}
tbGsxtZdryUpdate(promes).then((res) => {
proxy.$message.success('保存成功')
}).catch((err) => {
proxy.$message.error('保存失败')
});
console.log('submit!')
} else {
console.log('error submit!', fields)
}
})
}
const throwData = () => {
return new Promise((resolve) => {
resolve(ruleForm);
});
}
defineExpose({
throwData
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
.sumbitBtnBOX {
position: relative;
width: 100%;
height: 50px;
// background-color: saddlebrown;
.sumbitBtn {
position: absolute;
right: 18px;
bottom: 0px;
}
}
.backinfo-container>:nth-child(2) {
width: 100%;
// height: 50px;
justify-content: space-between;
.detentionFacility {
width: 100%;
display: flex;
align-items: baseline;
box-sizing: border-box;
padding: 20px;
justify-content: space-between;
}
.detentionFacility>:nth-child(1) {
width: 100px;
}
.detentionFacility>:nth-child(2) {
width: 98%;
display: flex;
flex-direction: column;
}
.detentionFacilityArr {
display: flex;
margin-top: 20px;
justify-content: space-between;
.el-form-item {
width: 93%;
height: 100%;
}
}
}
.background-info-input {
width: 100%;
margin-bottom: 15px;
}
.file-attachment-section {
margin-top: 15px;
}
.section-title {
font-size: 14px;
font-weight: 500;
color: #303133;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #ebeef5;
}
.file-list-container {
max-height: 100px;
overflow-y: auto;
border: 1px solid #ebeef5;
border-radius: 4px;
background-color: #ffffff;
margin-bottom: 10px;
}
/* 自定义滚动条样式 */
.file-list-container::-webkit-scrollbar {
width: 6px;
}
.file-list-container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
.file-list-container::-webkit-scrollbar-thumb {
background: #c0c4cc;
border-radius: 3px;
}
.file-list-container::-webkit-scrollbar-thumb:hover {
background: #909399;
}
.empty-file-list {
padding: 20px;
text-align: center;
color: #909399;
font-size: 12px;
}
.file-list {
padding: 5px;
}
.file-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 10px;
margin-bottom: 2px;
background-color: #f8f9fa;
border-radius: 4px;
transition: all 0.3s ease;
cursor: pointer;
}
.file-item:hover {
background-color: #e6f7ff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.file-info {
flex: 1;
display: flex;
align-items: center;
gap: 15px;
min-width: 0;
}
.file-name {
flex: 1;
font-size: 12px;
color: #303133;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.file-size {
font-size: 11px;
color: #909399;
min-width: 60px;
}
.file-time {
font-size: 11px;
color: #909399;
}
.file-actions {
display: flex;
align-items: center;
gap: 5px;
margin-left: 10px;
}
.file-actions .el-button {
padding: 0 5px;
margin: 0;
color: #606266;
transition: color 0.3s ease;
}
.file-actions .el-button:hover {
color: #409eff;
}
.delete-btn:hover {
color: #f56c6c !important;
}
.upload-btn-container {
display: flex;
justify-content: center;
margin-top: 10px;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.headClass::after {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 60px;
height: 2px;
background-color: #409eff;
}
h3 {
margin: 0;
}
</style>

View File

@ -0,0 +1,268 @@
<template>
<div class="backinfo-container">
<div class="headClass">
<h3>行为信息</h3>
</div>
<!-- 列表区域 -->
<div class="list-container">
<div v-loading="loading" class="behavior-list">
<div class="behavior-list-inner">
<div
v-for="(item, index) in behaviorList"
:key="item.id"
class="behavior-item"
>
<div class="behavior-item-header">
<span class="behavior-index">{{ index + 1 }}.</span>
<el-tag :type="getTagType(item.behaviorType)">{{ item.behaviorTypeName }}</el-tag>
<span class="behavior-time">{{ item.time }}</span>
</div>
<div class="behavior-item-content">
<p class="behavior-description">{{ item.description }}</p>
<p class="behavior-location"><i class="el-icon-location-outline"></i> {{ item.location }}</p>
</div>
</div>
<div v-if="!loading && behaviorList.length === 0" class="empty-state">
<el-empty description="暂无行为记录" />
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, getCurrentInstance, onMounted } from 'vue'
import GdMap from "@/components/GdMap/index.vue";
const { proxy } = getCurrentInstance();
const { D_BZ_ZJLX } = proxy.$dict("D_BZ_ZJLX")
// 搜索表单
const searchForm = ref({
behaviorType: '',
timeRange: null
})
// 列表数据
const behaviorList = ref([])
const loading = ref(false)
// 获取标签类型
const getTagType = (type) => {
const typeMap = {
'ticket': 'success',
'hotel': 'primary',
'border': 'warning',
'baseStation': 'info'
}
return typeMap[type] || 'default'
}
// 搜索
const handleSearch = () => {
fetchData()
}
// 重置搜索
const resetSearch = () => {
searchForm.value = {
behaviorType: '',
timeRange: null
}
fetchData()
}
// 获取数据
const fetchData = () => {
loading.value = true
// 模拟API请求延迟
setTimeout(() => {
// 模拟数据
const mockData = [
{
id: 1,
behaviorType: 'baseStation',
behaviorTypeName: '基站认证',
description: '2025-5-22 14:30:20出现在南宁市青秀区云网网咖',
location: '广西壮族自治区南宁市青秀区',
time: '2025-05-22 14:30:20'
}
]
// 根据搜索条件过滤数据
let filteredData = [...mockData]
if (searchForm.value.behaviorType) {
filteredData = filteredData.filter(item => item.behaviorType === searchForm.value.behaviorType)
}
if (searchForm.value.timeRange && searchForm.value.timeRange.length === 2) {
const [startTime, endTime] = searchForm.value.timeRange
filteredData = filteredData.filter(item => {
const itemTime = new Date(item.time)
return itemTime >= new Date(startTime) && itemTime <= new Date(endTime)
})
}
behaviorList.value = filteredData
loading.value = false
}, 500)
}
// 页面加载时获取数据
onMounted(() => {
fetchData()
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 20px;
width: 100%;
background-color: #f5f7fa;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 20px 0;
padding-bottom: 15px;
border-bottom: 2px solid #409eff;
position: relative;
}
h3 {
margin: 0;
}
.search-container {
background-color: #fff;
padding: 16px;
border-radius: 6px;
margin-bottom: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.demo-form-inline {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 16px;
}
.list-container {
background-color: #fff;
padding: 16px;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.behavior-list {
max-height: 600px;
overflow: hidden; /* 完全禁止滚动条 */
position: relative;
}
.behavior-list-inner {
max-height: 600px;
overflow-y: auto;
overflow-x: hidden;
padding-right: 10px; /* 为滚动条留出空间但不显示 */
}
.behavior-item {
padding: 16px;
border-bottom: 1px solid #f0f0f0;
transition: all 0.3s ease;
position: relative;
left: 0; /* 初始位置 */
}
.behavior-item:hover {
background-color: #fafafa;
left: 5px; /* 使用left属性代替transform避免触发滚动条 */
}
.behavior-item:last-child {
border-bottom: none;
}
.behavior-item-header {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.behavior-index {
font-weight: 600;
color: #606266;
margin-right: 12px;
min-width: 20px;
}
.behavior-time {
margin-left: auto;
color: #909399;
font-size: 13px;
}
.behavior-item-content {
padding-left: 32px;
}
.behavior-description {
margin: 0 0 8px 0;
color: #303133;
line-height: 1.5;
}
.behavior-location {
margin: 0;
color: #606266;
font-size: 13px;
line-height: 1.5;
}
.empty-state {
padding: 60px 0;
text-align: center;
}
::v-deep .el-tag {
margin-right: 0;
}
::v-deep .el-date-editor .el-range-separator {
color: #606266;
}
@media (max-width: 768px) {
.backinfo-container {
padding: 10px;
}
.demo-form-inline {
flex-direction: column;
align-items: stretch;
}
.demo-form-inline .el-form-item {
margin-bottom: 10px;
}
.pagination-container {
justify-content: center;
}
}
</style>

View File

@ -0,0 +1,263 @@
<template>
<div>
<div class="headClass" style="">
<h3>案件信息</h3>
<el-button @click="AddPore" type="primary" v-if="showBut">新增</el-button>
</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #controls="{ row }">
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
<el-link type="danger" @click="updDictItem(row)">修改</el-link>
</template>
</MyTable>
</div>
<CaseLodig v-model="chooseMarksVisible" @comfirm="addMarks" :data="dataModel" />
</template>
<script setup>
import { identityCardRule } from "@/utils/rules"
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import CaseLodig from "../component/caseLodig.vue";
import { tbGsxtZdryAjxxSaveOrUpdateAjxx, tbGsxtZdryAjxx, tbGsxtZdryAjxxselectAjxx } from '@/api/zdr.js'
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP } = proxy.$dict("D_BZ_CLLX", "D_BZ_CLYS", "D_BZ_CLPP"); //获取字典数据
const chooseMarksVisible = ref(false)
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const listData = ref({})
const addUpd = ref(true)
watch(() => props.dataList, (val) => {
if (val) {
listData.value = val
gettbZdryClxxSelectPage()
}
}, { deep: true })
// 表格数据
const pageData = reactive({
tableData: [],
tableColumn: [{
prop: 'ajbm',
label: '案件编号',
}, {
prop: 'ajmc',
label: '案件名称',
}, {
prop: 'sasj',
label: '受案时间',
},],
tableHeight: '200px',
keyCount: 0,
tableConfiger: {
border: true,
stripe: true,
showHeader: true,
showIndex: true,
indexLabel: '序号',
indexWidth: 60,
align: 'center',
showOverflowTooltip: true,
haveControls: !props.disabled
},
controlsWidth: 200,
})
// 修改数据接口
const dataModel = ref()
const addMarks = (val) => {
const params = {
...val,
zdryId: listData.value.id,
}
tbGsxtZdryAjxxSaveOrUpdateAjxx(params).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '案件信息操作成功',
type: 'success'
})
})
}
onMounted(() => {
})
// 删除车辆
const delDictItem = (val) => {
if (!props.disabled && props.showBut) {
ElMessageBox.confirm(
'是否删除案件信息',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
tbGsxtZdryAjxx(val).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '案件信息删除成功',
type: 'success'
})
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
} else {
pageData.tableData = pageData.tableData.filter(v => v.id != val)
}
}
const updDictItem = (val) => {
chooseMarksVisible.value = true
addUpd.value = false
dataModel.value = val
}
const AddPore = () => {
chooseMarksVisible.value = true
dataModel.value = {}
addUpd.value = true
}
// 查询车辆
const gettbZdryClxxSelectPage = () => {
const promes = {
zdrid: listData.value.id
}
tbGsxtZdryAjxxselectAjxx(promes).then(res => {
pageData.tableData = res
})
}
// 抛出数据并验证标签列表不为空
const throwData = () => {
return new Promise((resolve) => {
// // 验证:确保标签列表不为空
// if (!pageData.tableData || pageData.tableData.length === 0) {
// throw new Error('请录入车辆信息');
// }
resolve(pageData.tableData);
});
}
defineExpose({
throwData
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
::v-deep(.el-form) {
display: flex;
justify-content: space-between;
}
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
}
.headClass {
font-size: 18px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
color: #303133;
margin: 20px 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
}
.headSelect {
width: 100%;
padding: 0 16px;
background-color: #fff;
border-bottom: 1px solid #eee;
display: flex;
justify-content: end;
padding-bottom: 20px;
}
/* 移除冲突样式:不要用 justify-content */
/* 控制所有 el-form-item 高度和垂直居中 */
.form-inline :deep(.el-form-item) {
margin-bottom: 0;
height: 60px;
display: flex;
align-items: center;
}
/* ✅ 按钮区域靠右,且不换行 */
.form-inline .form-actions {
margin-left: auto;
/* 推到最右边 */
white-space: nowrap;
/* 防止按钮换行 */
}
/* 统一按钮样式,增加间距和视觉舒适度 */
.form-inline :deep(.el-button) {
height: 36px;
padding: 8px 16px;
font-size: 14px;
border-radius: 4px;
}
/* 按钮之间留出间距(除了第一个) */
.form-inline :deep(.el-button:not(:first-child)) {
margin-left: 12px;
/* 比原来的 8px 更宽松 */
}
// .headClass::after {
// content: '';
// position: absolute;
// left: 0;
// bottom: -2px;
// width: 60px;
// height: 2px;
// background-color: #409eff;
// }
h3 {
margin: 0;
}
</style>

View File

@ -0,0 +1,305 @@
<template>
<div>
<div class="headClass" style="">
<h3>密切联系人</h3>
<el-button type="primary" @click="openDialog('新增密切联系人', {}, true)" v-if="showBut">新增</el-button>
</div>
<div class="headSelect">
<el-form :model="formData" :inline="true" ref="formRef" :rules="rulesForm" class="form-inline">
<el-form-item label="身份证号码">
<el-input v-model="formData.rySfzh" placeholder="请输入身份证号码" />
</el-form-item>
<!-- 按钮组统一放在一个 item -->
<el-form-item class="form-actions">
<el-button type="primary" @click="check">查询</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #dygx="{ row }">
<DictTag :tag="false" :value="row.dygx" :options="D_BZ_QSGXDM" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
<el-link type="danger" @click="openDialog('修改密切联系人', row, false)">修改</el-link>
</template>
</MyTable>
<diaLogForm v-model="dialogVisible" :data="diaLogRuleForm" @submit="addPersonOrModifica" :title="Tips"
:dict="{ D_BZ_QSGXDM }">
</diaLogForm>
</div>
</template>
<script setup>
import { identityCardRule } from "@/utils/rules"
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import diaLogForm from "../component/diaLogForm.vue";
import { tbZdryClxxUpdate, tbGsxtZdryLxrsaveOrUpdateLxr,tbGsxtZdryLxrselectLxrBy ,tbGsxtZdryLxr} from '@/api/zdr.js'
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_BZ_QSGXDM } = proxy.$dict("D_BZ_QSGXDM"); //获取字典数据
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const dialogVisible = ref(false)
const listData = ref({})
const Tips = ref("密切联系人")
// 表格数据
const pageData = reactive({
tableData: [],
tableColumn: [{
prop: 'ryXm',
label: '人员姓名',
}, {
prop: 'rySfzh',
label: '身份证号码',
}, {
prop: 'dygx',
label: '关系',
showSolt: true,
}, {
prop: 'lxrDh',
label: '联系电话',
}],
tableHeight: '200px',
keyCount: 0,
tableConfiger: {
border: true,
stripe: true,
showHeader: true,
showIndex: true,
indexLabel: '序号',
indexWidth: 60,
align: 'center',
showOverflowTooltip: true,
haveControls: !props.disabled
},
controlsWidth: 200,
})
// 表单数据
const formData = ref({
username: "",
ID: ""
})
const touchIn = ref(true)
const rulesForm = ref(identityCardRule({ validator: true }, 'rySfzh'))
const diaLogRuleForm = ref({})
watch(() => props.dataList, (val) => {
if (val) {
listData.value = val
getContact()
}
}, { deep: true })
// 弹出增加或者修改弹窗
const openDialog = (type, formVal, bool) => {
touchIn.value = bool
dialogVisible.value = true
Tips.value = type
diaLogRuleForm.value = { ...formVal }
}
// 提交表单
const addPersonOrModifica = (val) => {
if (touchIn.value) {
const item = pageData.tableData.findIndex(item => item.rySfzh == val.rySfzh)
if (item != -1) {
proxy.$message({
message: '该人员已存在',
type: 'warning'
})
return
}
}
const promes = {
...val,
zdryId: listData.value.id
}
tbGsxtZdryLxrsaveOrUpdateLxr(promes).then((res) => {
proxy.$message({
message: '操作成功',
type: 'success'
})
getContact()
}).catch((err) => {
proxy.$message({
message: '操作失败',
type: 'error'
})
});
}
const delDictItem = (val) => {
ElMessageBox.confirm(
'是否删除该联系人',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
tbGsxtZdryLxr(val).then((res) => {
proxy.$message({
message: '删除成功',
type: 'success'
})
getContact()
}).catch((err) => {
});
})
.catch(() => {
proxy.$message({
message: '删除失败',
type: 'info',
})
})
}
const getContact = () => {
const promes = { zdryId: listData.value.id }
tbGsxtZdryLxrselectLxrBy(promes).then((res) => {
pageData.tableData = res
})
}
const resetForm = () => {
formData.value = {}
getContact()
}
const check = () => {
if (formData.value.rySfzh) {
// 模糊查询:检查身份证号码是否包含输入的内容
pageData.tableData = pageData.tableData.filter(item => item.rySfzh && item.rySfzh.includes(formData.value.rySfzh))
} else {
// 如果输入为空,显示所有数据
getContact()
}
}
// 抛出数据并验证标签列表不为空
const throwData = () => {
return new Promise((resolve) => {
// // 验证:确保标签列表不为空
// if (!pageData.tableData || pageData.tableData.length === 0) {
// throw new Error('请录入车辆信息');
// }
resolve(pageData.tableData);
});
}
defineExpose({
throwData
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.headSelect {
width: 100%;
padding: 0 16px;
background-color: #fff;
border-bottom: 1px solid #eee;
::v-deep(.el-form) {
display: flex;
justify-content: space-between;
}
/* 移除冲突样式:不要用 justify-content */
/* 控制所有 el-form-item 高度和垂直居中 */
.form-inline :deep(.el-form-item) {
margin-bottom: 0;
height: 60px;
display: flex;
align-items: center;
}
/* ✅ 按钮区域靠右,且不换行 */
.form-inline .form-actions {
margin-left: auto;
/* 推到最右边 */
white-space: nowrap;
/* 防止按钮换行 */
}
/* 统一按钮样式,增加间距和视觉舒适度 */
.form-inline :deep(.el-button) {
height: 36px;
padding: 8px 16px;
font-size: 14px;
border-radius: 4px;
}
/* 按钮之间留出间距(除了第一个) */
.form-inline :deep(.el-button:not(:first-child)) {
margin-left: 12px;
/* 比原来的 8px 更宽松 */
}
}
// .headClass::after {
// content: '';
// position: absolute;
// left: 0;
// bottom: -2px;
// width: 60px;
// height: 2px;
// background-color: #409eff;
// }
h3 {
margin: 0;
}
</style>

View File

@ -0,0 +1,222 @@
<template>
<div class="backinfo-container">
<div class="headClass">
<h3>操作日志</h3>
</div>
<!-- 列表区域 -->
<div class="list-container">
<div v-loading="loading" class="behavior-list">
<div class="behavior-list-inner">
<div
v-for="(item, index) in behaviorList"
:key="item.id"
class="behavior-item"
>
<div class="behavior-item-header">
<span class="behavior-index">{{ index + 1 }}.</span>
<el-tag :type="getTagType(item.behaviorType)">{{ item.zhmc }}</el-tag>
<span class="behavior-time">{{ item.czsj }}</span>
</div>
<div class="behavior-item-content">
<p class="behavior-description">{{ item.czjl }}</p>
<p class="behavior-location"><i class="el-icon-location-outline"></i> {{ item.bz }}</p>
</div>
</div>
<div v-if="!loading && behaviorList.length === 0" class="empty-state">
<el-empty description="暂无操作记录" />
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, getCurrentInstance, onMounted,watch } from 'vue'
import GdMap from "@/components/GdMap/index.vue";
import {tbGsxtZdryCzrzSelectCzrz} from '@/api/zdr'
const { proxy } = getCurrentInstance();
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const listData = ref({})
watch(() => props.dataList, (val) => {
if (val) {
listData.value = val
fetchData()
}
}, { deep: true })
// 列表数据
const behaviorList = ref([])
const loading = ref(false)
// 获取数据
const fetchData = () => {
loading.value = true
tbGsxtZdryCzrzSelectCzrz({ zdrid: listData.value.id }).then(res => {
behaviorList.value = res
}).finally(() => {
loading.value = false
})
}
// 页面加载时获取数据
onMounted(() => {
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding-top: 20px;
width: 100%;
background-color: #f5f7fa;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 20px 0;
padding-bottom: 15px;
border-bottom: 2px solid #409eff;
position: relative;
}
h3 {
margin: 0;
}
.search-container {
background-color: #fff;
padding: 16px;
border-radius: 6px;
margin-bottom: 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.demo-form-inline {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 16px;
}
.list-container {
background-color: #fff;
padding: 16px;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.behavior-list {
max-height: 600px;
overflow: hidden; /* 完全禁止滚动条 */
position: relative;
}
.behavior-list-inner {
max-height: 600px;
overflow-y: auto;
overflow-x: hidden;
padding-right: 10px; /* 为滚动条留出空间但不显示 */
}
.behavior-item {
padding: 16px;
border-bottom: 1px solid #f0f0f0;
transition: all 0.3s ease;
position: relative;
left: 0; /* 初始位置 */
}
.behavior-item:hover {
background-color: #fafafa;
left: 5px; /* 使用left属性代替transform避免触发滚动条 */
}
.behavior-item:last-child {
border-bottom: none;
}
.behavior-item-header {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.behavior-index {
font-weight: 600;
color: #606266;
margin-right: 12px;
min-width: 20px;
}
.behavior-time {
margin-left: auto;
color: #909399;
font-size: 13px;
}
.behavior-item-content {
padding-left: 32px;
}
.behavior-description {
margin: 0 0 8px 0;
color: #303133;
line-height: 1.5;
}
.behavior-location {
margin: 0;
color: #606266;
font-size: 13px;
line-height: 1.5;
}
.empty-state {
padding: 60px 0;
text-align: center;
}
::v-deep .el-tag {
margin-right: 0;
}
::v-deep .el-date-editor .el-range-separator {
color: #606266;
}
@media (max-width: 768px) {
.backinfo-container {
padding: 10px;
}
.demo-form-inline {
flex-direction: column;
align-items: stretch;
}
.demo-form-inline .el-form-item {
margin-bottom: 10px;
}
.pagination-container {
justify-content: center;
}
}
</style>

View File

@ -0,0 +1,101 @@
<template>
<div>
<div class="headClass" style="">
<h3>全要素布控</h3>
</div>
<div class="marginBox">
<div>身份证号码{{ listData.rySfzh }} <span>({{ listData.zdrBkZt ? '已布控' : '未布控' }})</span></div>
<div v-if="listData.ryLxdh&&listData.ryLxdh.length>0"> 手机号码
<span style="color: #000;" v-for="(item, index) in listData.ryLxdh" :key="index">{{ item }}
<span v-if="index != listData.ryLxdh.length - 1"></span>
</span>
<div> {{ listData.ryLxdh?.[1] }}<span>({{ listData.zdrBkZt ? '已布控' : '未布控' }})</span></div>
</div>
<div v-if="listData.clxxList">车牌号码
<span style="color: #000;" v-for="(item, index) in listData.clxxList" :key="index">{{ item.cph }}
<span v-if="index != listData.clxxList.length - 1"></span>
</span>
<span>({{ listData.zdrBkZt ? '已布控' : '未布控' }})</span>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const status = ref(false)
const listData = ref({})
watch(() => props.dataList, (val) => {
if (val) {
listData.value = val
}
}, { deep: true })
onMounted(() => {
console.log('Deployment 组件已挂载!')
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
border-bottom: 2px solid #409eff;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.marginBox {
span {
margin-left: 10px;
color: #ff4040;
}
&>:nth-child(1) {
// width: 300px;
height: 30px;
display: flex;
align-items: center;
}
&>:nth-child(2) {
// width: 400px;
height: 30px;
display: flex;
align-items: center;
// justify-content: space-between;
}
&>:nth-child(3) {
// width: 210px;
height: 30px;
display: flex;
align-items: center;
}
}
</style>

View File

@ -0,0 +1,106 @@
<template>
<div>
<div class="headClass" style="">
<h3>动态轨迹</h3>
</div>
<div class="headSelect">
<el-select v-model="listData.zjlx" placeholder="身份证号码" style="width: 240px">
<el-option v-for="item in D_BZ_ZJLX" :key="item.dm" :label="item.zdmc" :value="item.dm" />
</el-select>
<el-input v-model="listData.msg" placeholder="请输入证件号码" style="width: 300px" />
<div class="demo-datetime-picker">
<div class="block">
<el-date-picker v-model="listData.time" type="datetimerange" start-placeholder="开始时间"
end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss" date-format="YYYY/MM/DD ddd"/>
</div>
</div>
<el-button type="primary" @click="check">查询</el-button>
<el-button @click="resetForm">重置</el-button>
</div>
<div class="mapBox">
<GdMap />
</div>
</div>
</template>
<script setup>
import { ref, getCurrentInstance } from 'vue'
import GdMap from "@/components/GdMap/index.vue";
// import
const { proxy } = getCurrentInstance();
const { D_BZ_ZJLX } = proxy.$dict("D_BZ_ZJLX")
const listData= ref({})
const check = () => { }
const resetForm = () => {
listData.value = {}
}
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
::v-deep(.el-form) {
display: flex;
justify-content: space-between;
}
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
}
::v-deep .el-range-input{
color: #000 !important;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
}
.headSelect {
width: 100%;
margin: 20px 0;
padding: 0 16px;
background-color: #fff;
border-bottom: 1px solid #eee;
display: flex;
align-items: baseline;
justify-content: space-between;
}
.mapBox {
width: 100%;
height: 300px;
position: relative;
background-color: rgba(0, 123, 255, 0.5);
}
h3 {
margin: 0;
}
</style>

View File

@ -0,0 +1,346 @@
<template>
<div>
<div class="headClass">
<h3>人员信息</h3>
<!-- @click="gettbGsxtZdqtUpdate" -->
<el-button type="primary" v-if="showBut" :disabled="disabled" @click="submit">保存</el-button>
</div>
<div>
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" labelWidth="100px" ref="elform"
:rules="rules">
<template #ryzp>
<div style="width: 100%; padding-left: 50px">
<MOSTY.Upload :showBtn="false" :limit="1" v-model="listQuery.ryzp" />
</div>
</template>
<template #ryLxdh>
<div class="phone-input-container">
<div class="inputGroup" v-for="(item, index) in listQuery.ryLxdh" :key="index">
<el-input v-model="listQuery.ryLxdh[index]" class="group" placeholder="请输入电话号码" />
<div class="flex align-center but" v-if="showBut">
<el-button type="primary" :icon="Plus" circle @click="addPhone" title="添加电话号码"
v-if="listQuery.ryLxdh.length - 1 == index" />
<el-button type="success" :icon="Minus" circle @click="removePhone(index)" title="删除电话号码" />
</div>
</div>
</div>
</template>
</FormMessage>
</div>
</div>
<!-- <ChooseMarks v-model="chooseMarksVisible" @choosed="choosed" :roleIds="roleIds" /> -->
</template>
<script setup>
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { Plus, Minus } from "@element-plus/icons-vue";
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import ChooseMarks from "@/components/ChooseList/ChooseMarks/index.vue";
import { ref, reactive, onMounted, getCurrentInstance, watch } from "vue";
import { tbGsxtZdryUpdate } from "@/api/zdr.js";
const { proxy } = getCurrentInstance();
const { D_BZ_XB, D_BZ_ZZMM, D_BZ_HYZK, D_BZ_MZ, D_BZ_XZQHDM, D_ZDRY_RYLX, D_BZ_RCBKZT, D_GS_ZDR_RYJB, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_ZDR_CZZT, D_BZ_WHCD, D_ZDRY_ZYLB } =
proxy.$dict('D_BZ_XB', 'D_BZ_ZZMM', 'D_BZ_HYZK', 'D_BZ_MZ', "D_ZDRY_RYLX", 'D_BZ_XZQHDM', 'D_BZ_RCBKZT', 'D_GS_ZDR_RYJB', 'D_GS_ZDR_YJDJ', 'D_GS_BK_SSJZ', 'D_GS_ZDR_CZZT', 'D_BZ_WHCD', 'D_ZDRY_ZYLB')
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const rules = reactive({
ryXm: [{ required: true, message: "请输入姓名", trigger: "blur" }],
...rule.identityCardRule({ validator: true }, 'rySfzh'), //身份证校验
...rule.phoneRule({ validator: true }, "ryLxdh"), // 是否必填 是否进行校验,
rySfzh: [{ required: true, message: "请输入身份证号", trigger: "blur" }],
ryLxdh: [{ required: true, message: "请输入联系电话", trigger: "blur" }],
ryXb: [{ required: true, message: "请选择性别", trigger: "change" }],
zyBm: [{ required: true, message: "请选择职业", trigger: "change" }],
ryMz: [{ required: true, message: "请选择民族", trigger: "change" }],
ryCsrq: [{ required: true, message: "请选择出生日期", trigger: "change" }],
ryJg: [{ required: true, message: "请选择籍贯", trigger: "change" }],
zdrRyjb: [{ required: true, message: "请选择人员级别", trigger: "change" }],
zdrYjdj: [{ required: true, message: "请选择预警等级", trigger: "change" }],
// rylx: [{ required: true, message: "请选择人员类型", trigger: "change" }]
});
const listQuery = ref({ ryLxdh: [""] }); //表单
const chooseMarksVisible = ref(false); // 控制标签选择弹窗显示
const roleIds = ref([]); // 已选择的标签ID
const formData = ref([
{ label: "人员照片", prop: "ryzp", type: "slot", width: "100%" },
{ label: "姓名", prop: "ryXm", type: "input" },
{ label: "性别", prop: "ryXb", type: "select", options: D_BZ_XB },
{ label: "身份证号", prop: "rySfzh", type: "input" },
{ label: "籍贯", prop: "ryJg", type: "select", options: D_BZ_XZQHDM },
{ label: "曾用名", prop: "cym", type: "input" },
{ label: "文化程度", prop: "whcdBm", type: "select", options: D_BZ_WHCD },
{ label: "民族", prop: "ryMz", type: "select", options: D_BZ_MZ },
{ label: "政治面貌", prop: "zzmm", type: "select", options: D_BZ_ZZMM },
{ label: "职业", prop: "zyBm", type: "select", options: D_ZDRY_ZYLB },
{ label: "人员级别", prop: "zdrRyjb", type: "select", options: D_GS_ZDR_RYJB },
{ label: "预警等级", prop: "zdrYjdj", type: "select", options: D_GS_ZDR_YJDJ },
{ label: "出生日期", prop: "ryCsrq", type: "date" },
{ label: "户籍地区划", prop: "hjdQh", type: "select", options: D_BZ_XZQHDM },
{ label: "户籍地详址", prop: "hjdXz", type: "input" },
{ label: "户籍地派出所", prop: "hjdPcsdm",depMc:"hjdPcsmc" ,type: "department" },
{ label: "现住地区划", prop: "xzdQh", type: "select", options: D_BZ_XZQHDM },
{ label: "现住地详址", prop: "xzdXz", type: "input" },
{ label: "现住地派出所", prop: "xzdPcsdm",depMc:"xzdPcsmc" ,type: "department" },
{ label: "管辖单位", prop: "gxSsbmdm", depMc: 'gxSsbmmc', type: "department" },
{ label: "诉求单位", prop: "sqSsbmdm", depMc: 'sqSsbmmc', type: "department" },
{ label: "责任单位", prop: "zrSsbmdm", depMc: 'zrSsbmmc', type: "department" },
{ label: "所属警种", prop: "zdrSsjz", type: "select", options: D_GS_BK_SSJZ },
{ label: "涉及警种", prop: "zdrSjjz", type: "select", options: D_GS_BK_SSJZ, multiple: true },
{ label: "婚姻状态", prop: "hyzk", type: "select", options: D_BZ_HYZK },
// { label: "处置状态", prop: "zdrCzzt", type: "select", options: D_GS_ZDR_CZZT },
// { label: "布控状态", prop: "zdrBkZt", type: "select", options: D_BZ_RCBKZT },
// { label: "人员类型", prop: "rylx", type: "select", options: D_ZDRY_RYLX },
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime" },
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime" },
{ label: "Mac地址", prop: "macDz", type: "input" },
{ label: "联系电话", prop: "ryLxdh", type: "slot", width: "100%" },
// { label: "标签选择", prop: "tags", type: "slot", width: "100%" },
{ label: "管控原因", prop: "zdrLkyy", type: "textarea", width: "100%" },
]);
const loading = ref(false);
const elform = ref();
const disabled = ref(false);
// phoneList已重构为listQuery.value.ryLxdh
// 创建一个工具函数进行深拷贝
const deepClone = (obj) => {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (obj instanceof Array) {
return obj.map(item => deepClone(item));
}
const clonedObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = deepClone(obj[key]);
}
}
return clonedObj;
};
// 监听props.dataList变化处理初始化数据
watch(() => props.dataList, (val) => {
if (val) {
// 使用深拷贝避免直接引用同一个对象
listQuery.value = deepClone(val);
// 处理照片数据
listQuery.value.ryzp = val.ryzp == null || val.ryzp == '' ? [] : [val.ryzp];
listQuery.value.zdrSjjz = val.zdrSjjz == null || val.zdrSjjz == '' ? [] : JSON.parse(val.zdrSjjz);
// 处理标签ID数据确保数据回显
if (val.tagIds && Array.isArray(val.tagIds) && val.tagIds.length > 0) {
roleIds.value = [...val.tagIds];
} else if (val.bqIds && Array.isArray(val.bqIds) && val.bqIds.length > 0) {
roleIds.value = [...val.bqIds];
} else {
roleIds.value = [];
}
}
}, { deep: true })
// 提交
const submit = () => {
loading.value = true
gettbGsxtZdryUpdate()
};
//
const gettbGsxtZdryUpdate = () => {
const promes = {
...listQuery.value,
ryzp: listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : "",
ryLxdh: listQuery.value.ryLxdh,
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
}
elform.value.submit((data) => {
tbGsxtZdryUpdate(promes).then((res) => {
listQuery.value.ryzp = []
proxy.$message({
message: '更新成功',
type: 'success',
})
}).catch((err) => {
}).finally(() => {
loading.value = false
});
})
}
// 添加电话号码
const addPhone = () => {
// 确保新添加的电话号码与现有数据结构一致
// 创建深拷贝以避免响应式更新问题
const newPhoneList = [...listQuery.value.ryLxdh];
newPhoneList.push('');
// 用全新数组替换现有数组确保Vue正确检测到变化
listQuery.value.ryLxdh = newPhoneList;
}
// 删除电话号码
const removePhone = (index) => {
if (listQuery.value.ryLxdh.length > 1) {
listQuery.value.ryLxdh.splice(index, 1);
} else {
// 清空输入但保留输入框
listQuery.value.ryLxdh[0] = '';
proxy.$message.warning('至少保留一个联系电话');
}
}
const throwData = () => {
return new Promise((resolve, reject) => {
if (elform.value && elform.value.validate) {
elform.value.submit((data) => {
// 过滤掉空的电话号码
const validPhones = listQuery.value.ryLxdh.filter(phone => phone && phone.trim());
if (validPhones.length === 0) {
proxy.$message.warning('请至少输入一个有效的联系电话');
reject(new Error('请至少输入一个有效的联系电话'));
return;
}
resolve({
...listQuery.value,
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
ryLxdh: validPhones,
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
});
})
} else {
elform.value.submit((data) => {
// 如果没有验证方法,直接返回数据
const validPhones = listQuery.value.ryLxdh.filter(phone => phone && phone.trim());
if (validPhones.length === 0) {
proxy.$message.warning('请至少输入一个有效的联系电话');
reject(new Error('请至少输入一个有效的联系电话'));
return;
}
resolve({
...listQuery.value,
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
ryLxdh: validPhones,
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
});
})
}
});
};
defineExpose({
throwData,
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
width: 100%;
padding: 0 !important;
}
::v-deep .form-item-box {
width: 100% !important;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.headClass::after {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 60px;
height: 2px;
background-color: #409eff;
}
h3 {
margin: 0;
}
.phone-input-container {
display: flex;
// flex-direction: column;
flex-wrap: wrap;
width: 100%;
padding: 0;
}
.inputGroup {
margin-left: 10px;
width: 100%;
max-width: 400px;
display: flex;
align-items: center;
margin-bottom: 10px;
.group {
width: 250px;
margin-right: 10px;
}
.but {
display: flex;
gap: 5px;
}
}
::v-deep .el-button--primary {
background-color: #409eff !important;
border-color: #409eff !important;
}
::v-deep .el-button--success {
background-color: #67c23a !important;
border-color: #67c23a !important;
}
</style>

View File

@ -0,0 +1,211 @@
<template>
<div>
<div class="headClass" style="">
<h3>人员标签</h3>
<el-button type="primary" :disabled="disabled" @click="chooseMarksVisible = true">选择</el-button>
</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bqLx="{ row }">
<DictTag :tag="false" :value="row.bqLx" :options="D_GS_BQ_DJ" />
</template>
<template #bqLb="{ row }">
<DictTag :tag="false" :value="row.bqLb" :options="D_GS_SSYJ" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="danger" @click="delDictItem(row.bqId)">删除</el-link>
</template>
</MyTable>
</div>
<ChooseMarks v-model="chooseMarksVisible" @choosed="addMarks" :roleIds="roleIds" />
</template>
<script setup>
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import ChooseMarks from "@/components/ChooseList/ChooseMarks/index.vue";
import { tbGsxtZdryUpdate } from '@/api/zdr.js'
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_GS_BQ_DJ, D_GS_SSYJ } = proxy.$dict("D_GS_BQ_DJ", "D_GS_SSYJ"); //获取字典数据
const chooseMarksVisible = ref(false)
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const listData = ref({})
watch(() => props.dataList, (val) => {
if (val) {
listData.value = val
pageData.tableData = val.bqList
roleIds.value = val.bqList.map(v => v.bqId)
console.log(roleIds.value);
}
}, { deep: true })
const roleIds = ref([])
// 表格数据
const pageData = reactive({
tableData: [],
tableColumn: [{
prop: 'bqMc',
label: '标签名称',
showOverflowTooltip: true
}, {
prop: 'bqDm',
label: '标签代码',
}, {
showSolt: true,
prop: 'bqLx',
label: '标签类型',
}, {
showSolt: true,
prop: 'bqLb',
label: '标签类别',
}],
tableHeight: '200px',
keyCount: 0,
tableConfiger: {
border: true,
stripe: true,
showHeader: true,
showIndex: true,
indexLabel: '序号',
indexWidth: 60,
align: 'center',
showOverflowTooltip: true,
haveControls: !props.disabled
},
controlsWidth: 200,
})
// 修改数据接口
const zdqtUpdate = (val) => {
const params = {
id: listData.value.id,
bqList: pageData.tableData,
rySfzh: listData.value.rySfzh,
}
tbGsxtZdryUpdate(params).then(res => {
proxy.$message({
message: val,
type: 'success'
})
})
}
// 新增标签
const addMarks = (val) => {
pageData.tableData = val.map(v => {
return { bqDm: v.bqDm, bqId: v.id, bqLb: v.bqLb, bqLx: v.bqLx, bqMc: v.bqMc }
});
roleIds.value = val.map(v => v.id)
if (!props.disabled && props.showBut) {
zdqtUpdate("标签添加成功")
}
}
// 删除标签
const delDictItem = (val) => {
if (!props.disabled && props.showBut) {
ElMessageBox.confirm(
'是否删除标签',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
pageData.tableData = pageData.tableData.filter(v => v.bqId != val)
roleIds.value = roleIds.value.filter(v => v != val)
zdqtUpdate("标签删除成功")
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
} else {
pageData.tableData = pageData.tableData.filter(v => v.bqId != val)
roleIds.value = roleIds.value.filter(v => v != val)
}
}
// 抛出数据并验证标签列表不为空
const throwData = () => {
return new Promise((resolve) => {
// 验证:确保标签列表不为空
if (!pageData.tableData || pageData.tableData.length === 0) {
throw new Error('请选择群体标签');
}
resolve(pageData.tableData);
});
}
defineExpose({
throwData
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.headClass::after {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 60px;
height: 2px;
background-color: #409eff;
}
h3 {
margin: 0;
}
</style>

View File

@ -0,0 +1,248 @@
<template>
<div>
<div class="headClass" style="">
<h3>关联车辆</h3>
<el-button type="primary" :disabled="disabled" @click="AddPore" v-if="showBut">选择</el-button>
</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #clys="{ row }">
<DictTag :tag="false" :value="row.clys" :options="D_BZ_CLYS" />
</template>
<template #cllx="{ row }">
<DictTag :tag="false" :value="row.cllx" :options="D_BZ_CLLX" />
</template>
<template #clpp="{ row }">
<DictTag :tag="false" :value="row.clpp" :options="D_BZ_CLPP" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
<el-link type="danger" @click="updDictItem(row)">修改</el-link>
</template>
</MyTable>
</div>
<VehiclDoing v-model="chooseMarksVisible" @comfirm="addMarks" :data="dataModel"
:dict="{ D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP }" />
</template>
<script setup>
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import VehiclDoing from "../component/vehiclDoing.vue";
import { tbZdryClxxAdd, tbZdryClxxDelete, tbZdryClxxSelectPage, tbZdryClxxUpdate } from '@/api/zdr.js'
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_BZ_CLLX, D_BZ_CLYS, D_BZ_CLPP } = proxy.$dict("D_BZ_CLLX", "D_BZ_CLYS", "D_BZ_CLPP"); //获取字典数据
const chooseMarksVisible = ref(false)
const props = defineProps({
dataList: {
type: Object,
default: () => { },
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const listData = ref({})
const addUpd = ref(true)
watch(() => props.dataList, (val) => {
if (val) {
listData.value = val
gettbZdryClxxSelectPage()
}
}, { deep: true })
// 表格数据
const pageData = reactive({
tableData: [],
tableColumn: [{
prop: 'cph',
label: '车牌号',
}, {
prop: 'cllx',
label: '车辆类型',
showSolt: true,
prop: 'clpp',
}, {
showSolt: true,
prop: 'clys',
label: '车辆颜色',
}, {
showSolt: true,
prop: 'clpp',
label: '车辆品牌',
prop: 'clsbm',
label: '车辆识别码',
}],
tableHeight: '200px',
keyCount: 0,
tableConfiger: {
border: true,
stripe: true,
showHeader: true,
showIndex: true,
indexLabel: '序号',
indexWidth: 60,
align: 'center',
showOverflowTooltip: true,
haveControls: !props.disabled
},
controlsWidth: 200,
})
// 修改数据接口
const dataModel = ref()
const addMarks = (val) => {
const params = {
...val,
zdrid: listData.value.id,
}
if (props.showBut && !props.disabled) {
if (addUpd.value) {
tbZdryClxxAdd(params).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '关联车辆添加成功',
type: 'success'
})
})
}
else {
tbZdryClxxUpdate(params).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '关联车辆修改成功',
type: 'success'
})
})
}
} else {
pageData.tableData.push(val)
}
}
// 删除车辆
const delDictItem = (val) => {
if (!props.disabled && props.showBut) {
ElMessageBox.confirm(
'是否删除关联车辆',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
tbZdryClxxDelete({ ids: [val] }).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '关联车辆删除成功',
type: 'success'
})
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
} else {
pageData.tableData = pageData.tableData.filter(v => v.id != val)
}
}
const updDictItem = (val) => {
chooseMarksVisible.value = true
addUpd.value = false
dataModel.value = val
}
const AddPore = () => {
chooseMarksVisible.value = true
dataModel.value = {}
addUpd.value = true
}
// 查询车辆
const gettbZdryClxxSelectPage = () => {
const promes = {
pageCurrent: 1,
pageSize: 20,
zdrid: listData.value.id
}
tbZdryClxxSelectPage(promes).then(res => {
pageData.tableData = res.records
})
}
// 抛出数据并验证标签列表不为空
const throwData = () => {
return new Promise((resolve) => {
// // 验证:确保标签列表不为空
// if (!pageData.tableData || pageData.tableData.length === 0) {
// throw new Error('请录入车辆信息');
// }
resolve(pageData.tableData);
});
}
defineExpose({
throwData
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
}
.headClass {
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 0 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.headClass::after {
content: '';
position: absolute;
left: 0;
bottom: -2px;
width: 60px;
height: 2px;
background-color: #409eff;
}
h3 {
margin: 0;
}
</style>

View File

@ -0,0 +1,275 @@
<template>
<div>
<div class="headClass" style="">
<h3>走访记录</h3>
<el-button @click="AddPore" type="primary" v-if="showBut">新增</el-button>
</div>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="danger" @click="delDictItem(row.id)">删除</el-link>
<el-link type="danger" @click="updDictItem(row)">修改</el-link>
</template>
</MyTable>
</div>
<InterLoding v-model="chooseMarksVisible" @comfirm="addMarks" :data="dataModel" />
</template>
<script setup>
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted, onUnmounted } from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import InterLoding from "../component/interLoding.vue";
import { tbGsxtZdryZfjlsaveOrUpdateZfjl,tbGsxtZdryZfjlselectZfjl,tbGsxtZdryZfjl } from '@/api/zdr.js'
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const chooseMarksVisible = ref(false)
const props = defineProps({
dataList: {
type: Object,
default: () => {},
}, disabled: {
type: Boolean,
default: false
},
showBut: {
type: Boolean,
default: false
},
})
const listData = ref({})
const addUpd = ref(true)
watch(() => props.dataList, (val) => {
if (val) {
listData.value = {...val}
gettbZdryClxxSelectPage()
}
}, { deep: true })
// 表格数据
const pageData = reactive({
tableData: [],
tableColumn: [{
prop: 'zfmjXm',
width: 150,
label: '走访民警',
}, {
prop: 'zffs',
label: '走访方式',
}, {
prop: 'zfsj',
label: '走访时间',
}, {
prop: 'zfdz',
label: '走访地址',
},
{
prop: 'zfqk',
label: '走访情况',
}],
tableHeight: '200px',
keyCount: 0,
tableConfiger: {
border: true,
stripe: true,
showHeader: true,
showIndex: true,
indexLabel: '序号',
indexWidth: 60,
align: 'center',
showOverflowTooltip: true,
haveControls: !props.disabled
},
controlsWidth: 200,
})
// 修改数据接口
const dataModel = ref()
const addMarks = (val) => {
const params = {
...val,
zdryId: listData.value.id,
}
if (addUpd.value) {
tbGsxtZdryZfjlsaveOrUpdateZfjl(params).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '走访记录添加成功',
type: 'success'
})
})
}
else {
tbGsxtZdryZfjlsaveOrUpdateZfjl(params).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '走访记录修改成功',
type: 'success'
})
})
}
}
// 删除走访记录
const delDictItem = (val) => {
if (!props.disabled && props.showBut) {
ElMessageBox.confirm(
'是否删除走访记录',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
tbGsxtZdryZfjl(val).then(res => {
gettbZdryClxxSelectPage()
proxy.$message({
message: '走访记录删除成功',
type: 'success'
})
})
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
} else {
pageData.tableData = pageData.tableData.filter(v => v.id != val)
}
}
const updDictItem = (val) => {
chooseMarksVisible.value = true
addUpd.value = false
dataModel.value = val
}
const AddPore = () => {
chooseMarksVisible.value = true
dataModel.value = {}
addUpd.value = true
}
// 查询走访记录
const gettbZdryClxxSelectPage = () => {
const promes = {
zdrid: listData.value.id
}
tbGsxtZdryZfjlselectZfjl(promes).then(res => {
console.log(res, "走访记录");
pageData.tableData = res
})
}
// 抛出数据并验证标签列表不为空
const throwData = () => {
return new Promise((resolve) => {
resolve(pageData.tableData);
});
}
defineExpose({
throwData
})
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.backinfo-container {
padding: 10px;
}
::v-deep(.el-form) {
display: flex;
justify-content: space-between;
}
.left_box {
width: 200px;
border: 1px solid #c8c8c89a;
border-radius: 5px;
padding: 5px;
}
.right_box {
width: calc(100% - 230px);
overflow-y: auto;
padding: 5px;
}
::v-deep .el-form-item__content {
display: block !important;
}
.headClass {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 18px;
font-weight: 600;
color: #303133;
margin: 20px 0 10px 0;
padding-bottom: 10px;
border-bottom: 2px solid #409eff;
}
.headSelect {
width: 100%;
padding: 0 16px;
background-color: #fff;
border-bottom: 1px solid #eee;
display: flex;
justify-content: end;
padding-bottom: 20px;
}
/* 移除冲突样式:不要用 justify-content */
/* 控制所有 el-form-item 高度和垂直居中 */
.form-inline :deep(.el-form-item) {
margin-bottom: 0;
height: 60px;
display: flex;
align-items: center;
}
/* ✅ 按钮区域靠右,且不换行 */
.form-inline .form-actions {
margin-left: auto;
/* 推到最右边 */
white-space: nowrap;
/* 防止按钮换行 */
}
/* 统一按钮样式,增加间距和视觉舒适度 */
.form-inline :deep(.el-button) {
height: 36px;
padding: 8px 16px;
font-size: 14px;
border-radius: 4px;
}
/* 按钮之间留出间距(除了第一个) */
.form-inline :deep(.el-button:not(:first-child)) {
margin-left: 12px;
/* 比原来的 8px 更宽松 */
}
// .headClass::after {
// content: '';
// position: absolute;
// left: 0;
// bottom: -2px;
// width: 60px;
// height: 2px;
// background-color: #409eff;
// }
h3 {
margin: 0;
}
</style>

View File

@ -53,10 +53,8 @@
<DictTag :tag="false" :value="row.qtFxdj" :options="D_GS_ZDQT_FXDJ" /> <DictTag :tag="false" :value="row.qtFxdj" :options="D_GS_ZDQT_FXDJ" />
</template> </template>
<template #bqList="{ row }"> <template #bqList="{ row }">
<ul> <span class="one_text_detail marks mr2" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{ item.bqFz || 0 }} ) </span>
item.bqFz || 0 }} ) </li>
</ul>
</template> </template>
<template #zdryList="{ row }"> <template #zdryList="{ row }">
<span style="color: #0072ff">{{ row.zdryList ? row.zdryList.length : 0 }}</span> <span style="color: #0072ff">{{ row.zdryList ? row.zdryList.length : 0 }}</span>
@ -173,20 +171,18 @@ const pageData = reactive({
}, },
controlsWidth: 280, controlsWidth: 280,
tableColumn: [ tableColumn: [
{ label: "群体名称", prop: "qtMc", width: 150 }, { label: "群体名称", prop: "qtMc" },
{ label: "群体类别", prop: "qtLb", showSolt: true, width: 150 }, { label: "群体类别", prop: "qtLb", showSolt: true },
{ label: "风险等级", prop: "qtFxdj", showSolt: true, width: 150 }, { label: "风险等级", prop: "qtFxdj", showSolt: true },
{ label: "背景资料", prop: "qtBjzl", width: 150 }, // { label: "背景资料", prop: "qtBjzl" },
{ label: "背景信息", prop: "bgxx", showSolt: true, width: 150 }, { label: "背景信息", prop: "bgxx", showSolt: true },
{ label: "管辖单位", prop: "gxSsdwmc", width: 150 }, { label: "管辖单位", prop: "gxSsdwmc" },
{ label: "列控原因", prop: "zdrLkyy", width: 150 }, { label: "列控原因", prop: "zdrLkyy" },
{ label: "开始时间", prop: "zdrRkkssj", width: 150 }, { label: "开始时间", prop: "zdrRkkssj" },
{ label: "截至时间", prop: "zdrRkjssj", width: 150 }, { label: "截至时间", prop: "zdrRkjssj" },
{ label: "稳控人数", prop: "zdryList", showSolt: true, width: 150 }, { label: "稳控人数", prop: "zdryList", showSolt: true },
{ label: "状态", prop: "qtZt", showSolt: true, width: 150 }, { label: "状态", prop: "qtZt", showSolt: true },
{ label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true, width: 400 }, { label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true, },
{ label: "创建单位", prop: "xtCjbmmc", width: 150 },
{ label: "创建时间", prop: "xtCjsj", width: 150 },
] ]
}); });
@ -328,7 +324,7 @@ defineExpose({});
<style lang="scss" scoped> <style lang="scss" scoped>
.marks { .marks {
padding: 0 4px; padding: 0 2px;
white-space: nowrap; white-space: nowrap;
background: #73acf1; background: #73acf1;
border-radius: 4px; border-radius: 4px;

View File

@ -207,7 +207,7 @@ const submit = async () => {
info.value.throwData() info.value.throwData()
// personnelTags.value.throwData(), // personnelTags.value.throwData(),
]); ]);
tbGsxtZdrySave(infoData).then(res => { tbGsxtZdrySave({...infoData,rylx:'01'}).then(res => {
proxy.$message({ proxy.$message({
message: '新增成功', message: '新增成功',
type: 'success', type: 'success',

View File

@ -65,7 +65,7 @@
<DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB" /> <DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB" />
</template> </template>
<template #zdrBkZt="{ row }"> <template #zdrBkZt="{ row }">
<DictTag :tag="false" :value="row.zdrBkZt" :options="D_GS_ZDR_BK_ZT" /> <DictTag :tag="false" :value="row.zdrBkZt" :options="D_ZDRGK_GKZT" />
</template> </template>
<template #zdrCzzt="{ row }"> <template #zdrCzzt="{ row }">
<DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" /> <DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" />
@ -96,7 +96,7 @@
</div> </div>
<!-- 详情 --> <!-- 详情 -->
<AddForm ref="addFormDiloag" @updateDate="getList" <AddForm ref="addFormDiloag" @updateDate="getList"
:dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" /> :dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_ZDRGK_GKZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" />
<!-- 选择用户 --> <!-- 选择用户 -->
<ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" /> <ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" />
<!-- 转线索 --> <!-- 转线索 -->
@ -120,8 +120,8 @@ import { useRouter, useRoute } from 'vue-router'
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } = const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_ZDRGK_GKZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
proxy.$dict("D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX"); proxy.$dict("D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_ZDRGK_GKZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
const obj = ref({}); const obj = ref({});
const showzxs = ref(false); const showzxs = ref(false);
const zxsDilof = ref(); const zxsDilof = ref();
@ -176,22 +176,16 @@ const pageData = reactive({
}, },
controlsWidth: 250, controlsWidth: 250,
tableColumn: [ tableColumn: [
{ label: "姓名", prop: "ryXm", width: 150 }, { label: "姓名", prop: "ryXm",width: 100 },
{ label: "性别", prop: "ryXb", showSolt: true, width: 100 }, { label: "性别", prop: "ryXb", showSolt: true, width: 80 },
{ label: "籍贯", prop: "ryJg", showSolt: true, width: 100 }, { label: "身份证", prop: "rySfzh", width: 170 },
{ label: "身份证", prop: "rySfzh", width: 200 }, { label: "民族", prop: "ryMz", showSolt: true, width: 80 },
{ label: "民族", prop: "ryMz", showSolt: true, width: 100 }, { label: "户籍派出所", prop: "hjdPcsmc" },
{ label: "户籍地区划", prop: "hjdQh", showSolt: true, width: 150 }, { label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true },
{ label: "户籍派出所", prop: "hjdPcsmc", width: 200 }, { label: "管辖单位", prop: "gxSsbmmc" },
{ label: "户籍地详址", prop: "hjdXz", width: 200 }, { label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true,showSolt: true, width: 100 },
{ label: "标签", prop: "bqList", showSolt: true, width: 400, showOverflowTooltip: true }, { label: "审核状态", prop: "zdrZt", showSolt: true, width: 100 },
{ label: "管辖单位", prop: "gxSsbmmc", width: 200 }, { label: "入库时间", prop: "zdrRkkssj", },
{ label: "人员级别", prop: "zdrRyjb", showSolt: true, width: 130 },
{ label: "管控原因", prop: "zdrLkyy", width: 200, showOverflowTooltip: true },
{ label: "管控状态", prop: "zdrBkZt", width: 200, showOverflowTooltip: true },
{ label: "处置状态", prop: "zdrCzzt", showSolt: true },
{ label: "审核状态", prop: "zdrZt", showSolt: true },
{ label: "状态", prop: "xtSjzt", showSolt: true },
] ]
}); });
@ -227,7 +221,7 @@ const getList = () => {
pageData.tableConfiger.loading = true; pageData.tableConfiger.loading = true;
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉 // 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
// rylx: '01', // rylx: '01',
let data = {...pageData.pageConfiger, ...queryFrom.value }; let data = {...pageData.pageConfiger, ...queryFrom.value,rylx: '01' };
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => { qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
pageData.tableData = res.records || []; pageData.tableData = res.records || [];
pageData.total = res.total; pageData.total = res.total;

View File

@ -6,11 +6,12 @@
<template #reference> <template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button> <el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
</template> </template>
<div class="flex just-center"> <div class="flex just-center">
<el-button size="small" type="primary" v-for="it in D_GS_BK_SQLX" :key="it.dm" @click="handleApplication(it)" >{{ it.zdmc }}</el-button> <el-button size="small" type="primary" v-for="it in D_GS_BK_SQLX" :key="it.dm" @click="handleApplication(it)">{{
</div> it.zdmc }}</el-button>
</el-popover> </div>
<el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click"> </el-popover>
<el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click">
<template #reference> <template #reference>
<el-button size="small" type="primary" @click="(visiblefp = !visiblefp), (visible = false)" >指定分配</el-button> <el-button size="small" type="primary" @click="(visiblefp = !visiblefp), (visible = false)" >指定分配</el-button>
</template> </template>
@ -21,55 +22,67 @@
<el-button type="primary" @click="handlefp" size="small">分配</el-button> <el-button type="primary" @click="handlefp" size="small">分配</el-button>
</div> </div>
</div> </div>
</el-popover> </el-popover>
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button> <el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> --> <el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
<!-- </PageTitle> <!-- </PageTitle>
</div> --> </div> -->
<!-- 搜索 --> <!-- 搜索 -->
<div ref="searchBox" class="mt10 mb10"> <div ref="searchBox" class="mt10 mb10">
<Search :searchArr="searchConfiger" @submit="onSearch" /> <Search :searchArr="searchConfiger" @submit="onSearch" />
</div> </div>
<!-- <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left>
<el-button type="primary" @click="showYpdolog = true" size="small" :disabled="!ids.length">批量审批</el-button>
</template>
</PageTitle> -->
<!-- 表格 --> <!-- 表格 -->
<div class="tabBox heightBox"> <div class="tabBox heightBox">
<MyTable <MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:tableData="pageData.tableData" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
:tableColumn="pageData.tableColumn" @chooseData="chooseData">
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
@chooseData="chooseData"
>
<template #ryxx="{ row }"> <template #ryxx="{ row }">
<div class="flex"> <div class="flex">
<img src="" alt="" style="width: 80px;height: 90px;" /> <img src="" alt="" style="width: 80px;height: 90px;" />
<ul class="tl ml10" style="flex:1 0 0"> <ul class="tl ml10" style="flex:1 0 0">
<li class="one_text_detail">姓名{{ row.ryXm }}</li> <li class="one_text_detail">姓名{{ row.ryXm }}</li>
<li class="flex one_text_detail">性别<DictTag :tag="false" :value="row.ryXb" :options="D_BZ_XB" /></li> <li class="flex one_text_detail">性别
<li class="flex one_text_detail">籍贯<DictTag :tag="false" :value="row.ryJg" :options="D_BZ_XZQHDM"/></li> <DictTag :tag="false" :value="row.ryXb" :options="D_BZ_XB" />
</li>
<li class="flex one_text_detail">籍贯
<DictTag :tag="false" :value="row.ryJg" :options="D_BZ_XZQHDM" />
</li>
<li class="one_text_detail">身份证{{ row.rySfzh }}</li> <li class="one_text_detail">身份证{{ row.rySfzh }}</li>
<li class="one_text_detail">出生日期{{ row.ryCsrq }}</li> <li class="one_text_detail">出生日期{{ row.ryCsrq }}</li>
<li class="flex one_text_detail">民族<DictTag :tag="false" :value="row.ryMz" :options="D_BZ_MZ" /></li> <li class="flex one_text_detail">民族
<DictTag :tag="false" :value="row.ryMz" :options="D_BZ_MZ" />
</li>
</ul> </ul>
</div> </div>
</template> </template>
<template #bqList="{ row }"> <template #bqList="{ row }">
<ul > <ul>
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{ item.bqFz || 0 }} ) </li> <li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
item.bqFz || 0 }} ) </li>
</ul> </ul>
</template> </template>
<template #jzxx="{ row }"> <template #jzxx="{ row }">
<div class="flex one_text_detail">户籍地区划<DictTag :tag="false" :value="row.hjdQh" :options="D_BZ_XZQHDM" /></div> <div class="flex one_text_detail">户籍地区划
<DictTag :tag="false" :value="row.hjdQh" :options="D_BZ_XZQHDM" />
</div>
<div class="flex one_text_detail">户籍派出所{{ row.hjdPcsmc }}</div> <div class="flex one_text_detail">户籍派出所{{ row.hjdPcsmc }}</div>
<div class="flex one_text_detail">户籍地详址{{ row.hjdXz }}</div> <div class="flex one_text_detail">户籍地详址{{ row.hjdXz }}</div>
</template> </template>
<template #gxdw="{ row }"> <template #gxdw="{ row }">
<div class="flex one_text_detail">管辖单位{{ row.gxSsbmmc }}</div> <div class="flex one_text_detail">管辖单位{{ row.gxSsbmmc }}</div>
<div class="flex">人员级别<DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB"/> </div> <div class="flex">人员级别
<DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB" />
</div>
<div class="flex one_text_detail">管控原因{{ row.zdrLkyy }}</div> <div class="flex one_text_detail">管控原因{{ row.zdrLkyy }}</div>
<div class="flex">管控状态<DictTag :tag="false" :value="row.zdrBkZt" :options="D_GS_ZDR_BK_ZT" /></div> <div class="flex">管控状态
<DictTag :tag="false" :value="row.zdrBkZt" :options="D_GS_ZDR_BK_ZT" />
</div>
</template> </template>
<template #zdrCzzt="{ row }"> <template #zdrCzzt="{ row }">
<DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" /> <DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" />
@ -85,14 +98,17 @@
<template #controls="{ row }"> <template #controls="{ row }">
<el-popover placement="left" :visible="row.visible" :width="400" trigger="manual"> <el-popover placement="left" :visible="row.visible" :width="400" trigger="manual">
<template #reference> <template #reference>
<el-link size="small" type="warning" v-if="row.zdrZt == '02'" @click="row.visible = !row.visible,chooseRow.id = row.id">审核</el-link> <el-link size="small" type="warning" v-if="row.zdrZt == '02'"
@click="row.visible = !row.visible, chooseRow.id = row.id">审核</el-link>
</template> </template>
<el-form :model="chooseRow" ref="elRowForm" :inline="true" label-width="100px" :rules="rules"> <el-form :model="chooseRow" ref="elRowForm" :inline="true" label-width="100px" :rules="rules">
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;"> <el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;">
<MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable placeholder="请选择是否通过"/> <MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable
placeholder="请选择是否通过" />
</el-form-item> </el-form-item>
<el-form-item label="不通过原因" prop="shBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;"> <el-form-item label="不通过原因" prop="shBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;">
<MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.shBtgyy" type="textarea" placeholder="请输入不通过原因"/> <MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.shBtgyy" type="textarea"
placeholder="请输入不通过原因" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="flex just-center mt10"> <div class="flex just-center mt10">
@ -103,14 +119,17 @@
<el-popover placement="left" :visible="row.visible1" :width="400" trigger="manual"> <el-popover placement="left" :visible="row.visible1" :width="400" trigger="manual">
<template #reference> <template #reference>
<el-link size="small" type="primary" v-if="row.zdrZt == '04'" @click="row.visible1 = !row.visible1,chooseRow.id = row.id">审批</el-link> <el-link size="small" type="primary" v-if="row.zdrZt == '04'"
@click="row.visible1 = !row.visible1, chooseRow.id = row.id">审批</el-link>
</template> </template>
<el-form :model="chooseRow" ref="elRowForm1" :inline="true" label-width="100px" :rules="rules"> <el-form :model="chooseRow" ref="elRowForm1" :inline="true" label-width="100px" :rules="rules">
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;"> <el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;">
<MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable placeholder="请选择是否通过"/> <MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable
placeholder="请选择是否通过" />
</el-form-item> </el-form-item>
<el-form-item label="不通过原因" prop="spBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;"> <el-form-item label="不通过原因" prop="spBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;">
<MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.spBtgyy" type="textarea" placeholder="请输入不通过原因"/> <MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.spBtgyy" type="textarea"
placeholder="请输入不通过原因" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="flex just-center mt10"> <div class="flex just-center mt10">
@ -119,25 +138,23 @@
</div> </div>
</el-popover> </el-popover>
<el-link size="small" type="primary" @click="addEdit('detail', row)" >详情</el-link> <el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
</template> </template>
</MyTable> </MyTable>
<Pages <Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="{
...pageData.pageConfiger, ...pageData.pageConfiger,
total: pageData.total total: pageData.total
}" }"></Pages>
></Pages>
</div> </div>
<!-- 详情 --> <!-- 详情 -->
<AddForm ref="addFormDiloag" @updateDate="getList" :dic="{D_GS_ZDR_RYJB,D_BZ_XB,D_BZ_MZ,D_BZ_XZQHDM,D_GS_ZDR_BK_ZT,D_GS_ZDR_CZZT,D_GS_BQ_ZL,D_GS_BQ_LB,D_GS_BQ_LX,D_GS_ZDR_YJDJ,D_GS_BK_SSJZ}"/> <AddForm ref="addFormDiloag" @updateDate="getList"
:dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" />
<!-- 选择用户 --> <!-- 选择用户 -->
<ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds"/> <ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" />
<!-- 转线索 --> <!-- 转线索 -->
<ZxsForm v-if="showzxs" ref="zxsDilof" @change="getList" :dic="{D_BZ_SF,D_BZ_XB,D_GS_XS_LY,D_BZ_SSZT,D_GS_XS_LX,D_GS_XS_QTLX }"></ZxsForm> <ZxsForm v-if="showzxs" ref="zxsDilof" @change="getList"
:dic="{ D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX }"></ZxsForm>
<Ypdolog v-model="showYpdolog" :dataList="ids"/>
</div> </div>
</template> </template>
@ -152,9 +169,10 @@ import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue"; import Search from "@/components/aboutTable/Search.vue";
import AddForm from "../mpvPeo/components/addForm.vue"; import AddForm from "../mpvPeo/components/addForm.vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js"; import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import Ypdolog from "./ypdolog.vue";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { D_GS_ZDQT_ZT,D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } = proxy.$dict("D_GS_ZDQT_ZT","D_GS_ZDR_RYJB","D_BZ_XB","D_BZ_MZ","D_BZ_XZQHDM","D_GS_ZDR_BK_ZT","D_GS_ZDR_CZZT","D_GS_BQ_ZL","D_GS_BQ_LB","D_GS_BQ_LX","D_GS_ZDR_YJDJ","D_GS_BK_SSJZ","D_GS_BK_SQLX","D_BZ_SF","D_GS_XS_LY","D_BZ_SSZT","D_GS_XS_LX","D_GS_XS_QTLX"); const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } = proxy.$dict("D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
const obj = ref({}); const obj = ref({});
const showzxs = ref(false); const showzxs = ref(false);
const zxsDilof = ref(); const zxsDilof = ref();
@ -226,10 +244,10 @@ const pageData = reactive({
}, },
controlsWidth: 120, controlsWidth: 120,
tableColumn: [ tableColumn: [
{ label: "重点人员信息", prop: "ryxx", showSolt: true,width:300,showOverflowTooltip:true }, { label: "重点人员信息", prop: "ryxx", showSolt: true, width: 300, showOverflowTooltip: true },
{ label: "户籍居住信息", prop: "jzxx", showSolt: true,width:300, }, { label: "户籍居住信息", prop: "jzxx", showSolt: true, width: 300, },
{ label: "标签", prop: "bqList", showSolt: true ,width:200,showOverflowTooltip:true}, { label: "标签", prop: "bqList", showSolt: true, width: 200, showOverflowTooltip: true },
{ label: "管辖单位", prop: "gxdw", showSolt: true,width:300, }, { label: "管辖单位", prop: "gxdw", showSolt: true, width: 300, },
{ label: "处置状态", prop: "zdrCzzt", showSolt: true }, { label: "处置状态", prop: "zdrCzzt", showSolt: true },
{ label: "状态", prop: "xtSjzt", showSolt: true }, { label: "状态", prop: "xtSjzt", showSolt: true },
{ label: "审核状态", prop: "zdrZt", showSolt: true }, { label: "审核状态", prop: "zdrZt", showSolt: true },
@ -260,7 +278,7 @@ const changeSize = (val) => {
// 获取列表 // 获取列表
const getList = () => { const getList = () => {
pageData.tableConfiger.loading = true; pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value,zdrZt:'02' }; let data = { ...pageData.pageConfiger, ...queryFrom.value, zdrZt: '02' };
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => { qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
pageData.tableData = res.records || []; pageData.tableData = res.records || [];
pageData.total = res.total; pageData.total = res.total;
@ -295,7 +313,7 @@ const handleUserSelected = (val) => {
// 处理分配 // 处理分配
const handlefp = () => { const handlefp = () => {
if (ids.value.length === 0) return ElMessage.error("请先选择需要布控的重点人"); if (ids.value.length === 0) return ElMessage.error("请先选择需要布控的重点人");
qcckPost({ ids: ids.value, uid: obj.value.fpid },"/mosty-gsxt/tbGsxtZdry/addGkmj").then(() => { qcckPost({ ids: ids.value, uid: obj.value.fpid }, "/mosty-gsxt/tbGsxtZdry/addGkmj").then(() => {
ElMessage.success("分配成功"); ElMessage.success("分配成功");
visible.value = false; visible.value = false;
visiblefp.value = false; visiblefp.value = false;
@ -336,47 +354,47 @@ const cancelRow = (row) => {
}; };
// 审核 // 审核
const handleSend = (val) =>{ const handleSend = (val) => {
elRowForm.value.validate((valid) => { elRowForm.value.validate((valid) => {
if(!valid) return; if (!valid) return;
btnloading.value = true; btnloading.value = true;
qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSh").then(() => { qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSh").then(() => {
proxy.$message({ type: "success", message: "审核成功" }); proxy.$message({ type: "success", message: "审核成功" });
cancelRow(val) cancelRow(val)
getList(); getList();
}).catch(()=>{ }).catch(() => {
btnloading.value = false; btnloading.value = false;
}); });
}) })
} }
// 审批 // 审批
const cancelRowSp = (row) =>{ const cancelRowSp = (row) => {
row.visible1 = false; row.visible1 = false;
chooseRow.value = {}; chooseRow.value = {};
btnloading.value = false; btnloading.value = false;
elRowForm1.value.resetFields() elRowForm1.value.resetFields()
} }
// 审批 // 审批
const handleSendSp = (val) =>{ const handleSendSp = (val) => {
elRowForm1.value.validate((valid) => { elRowForm1.value.validate((valid) => {
if(!valid) return; if (!valid) return;
btnloading.value = true; btnloading.value = true;
qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSp").then(() => { qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSp").then(() => {
proxy.$message({ type: "success", message: "审批成功" }); proxy.$message({ type: "success", message: "审批成功" });
cancelRowSp(val); cancelRowSp(val);
getList(); getList();
}).catch(()=>{ }).catch(() => {
btnloading.value = false; btnloading.value = false;
}); });
}) })
} }
const showYpdolog=ref(false)
//新增编辑 //新增编辑
const addEdit = (type, row) => { const addEdit = (type, row) => {
show.value = true; show.value = true;
nextTick(()=>{ nextTick(() => {
addFormDiloag.value.init(type, row); addFormDiloag.value.init(type, row);
}) })
}; };
@ -391,7 +409,7 @@ const tabHeightFn = () => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.marks{ .marks {
padding: 0 4px; padding: 0 4px;
white-space: nowrap; white-space: nowrap;
background: #73acf1; background: #73acf1;
@ -404,5 +422,4 @@ const tabHeightFn = () => {
.el-loading-mask { .el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important; background: rgba(0, 0, 0, 0.5) !important;
} }
</style> </style>

View File

@ -0,0 +1,103 @@
<template>
<el-dialog :model-value="modelValue" title="内部审核" width="35%" @close="closeDialog" destroy-on-close append-to-body>
<div style="height: 15vh; overflow: auto;">
<el-form ref="ruleFormRef" :rules="rules" :model="form" label-width="auto" style="max-width: 600px">
<el-form-item label="审核状态" prop="shzt">
<el-radio-group v-model="form.sftg">
<el-radio label="01">通过</el-radio>
<el-radio label="02">拒绝</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="审核意见" prop="shyj">
<el-input v-model="form.spBtgyy" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeDialog(ruleFormRef)">取消</el-button>
<el-button type="primary" @click="submitForm(ruleFormRef)">确认 </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import { ref, reactive, getCurrentInstance, watch } from "vue";
import { ypbgSjzlYpsp } from '@/api/huiShangyp/strategicApi.js'
const { proxy } = getCurrentInstance()
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dataList: {
type: Array,
default: () => ([])
}
})
const emit = defineEmits(['update:modelValue','getList'])
const closeDialog = (formEl) => {
if (!formEl) return
formEl.resetFields()
emit('update:modelValue', false)
}
const rules = reactive({
shzt: [
{ required: true, message: '请选择审核状态', trigger: 'blur' }
],
shyj: [
{ required: true, message: '请输入审核意见', trigger: 'blur' }
]
})
const ruleFormRef = ref(null)
const form = reactive({
shzt: '',
shyj: ''
})
const handleSendSpPl = (val) => {
proxy.$confirm("是否确定审批?", "警告", { type: "warning" }).then(() => {
qcckPost({ids:ids.value}, "/mosty-gsxt/tbGsxtZdry/batchSh").then(() => {
proxy.$message({ type: "success", message: "审批成功" });
cancelRowSp(val);
getList();
}).catch(() => {
btnloading.value = false;
});
})
}
const submitForm = async (formEl) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
const promise = {
...form,
ypid: props.dataList
}
ypbgSjzlYpsp(promise).then(res => {
proxy.$message({
message: '操作成功',
type: 'success'
})
emit('getList')
formEl.resetFields()
emit('update:modelValue', false)
})
} else {
console.log('error submit!', fields)
}
})
}
</script>
<style scoped></style>

View File

@ -0,0 +1,26 @@
<template>
<div>
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left>
<el-button size="small" v-for="el in tabBtn" :type="tabActive==el?'primary':''" @click="tabActive=el" :key="el">{{ el }}</el-button>
</template>
</PageTitle>
<ZdrSP v-if="tabActive == '重点人审批'" />
<ZdqtSP v-if="tabActive == '重点群体审批'" />
</div>
</template>
<script setup>
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import ZdrSP from "@/views/backOfficeSystem/DeploymentDisposal/mpvPeoSh/index";
import ZdqtSP from "@/views/backOfficeSystem/DeploymentDisposal/mpvGroupSh/index";
import { ref } from "vue";
const tabBtn=ref(["重点人审批","重点群体审批"])
const tabActive=ref('重点人审批')
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>

View File

@ -73,8 +73,8 @@ const qxkz = reactive({
const searchConfiger = ref([ const searchConfiger = ref([
{ label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" }, { label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" },
// { label: "情报来源", prop: 'cjLx', placeholder: "请选择情报来源", showType: "select", options: D_BZ_CJLX }, { label: "时间", prop: 'times', placeholder: "请输入时间", showType: "datetimerange" },
// { label: "来源单位", prop: 'ssbmdm', placeholder: "请选择来源单位", showType: "department" } { label: "部门", prop: 'ssbmdm', placeholder: "请选择来源单位", showType: "department" }
]); ]);
const pageData = reactive({ const pageData = reactive({
@ -90,13 +90,14 @@ const pageData = reactive({
pageSize: 20, pageSize: 20,
pageCurrent: 1 pageCurrent: 1
}, },
controlsWidth: 240, controlsWidth: 100,
tableColumn: [ tableColumn: [
{ label: "情报标题", prop: "qbmc" }, { label: "情报标题", prop: "qbmc",width:250 },
{ label: "编号", prop: "xsBh",width:190 },
// { label: "情报类型", prop: "qblx", showSolt: true }, // { label: "情报类型", prop: "qblx", showSolt: true },
// { label: "情报来源", prop: "cjlx", showSolt: true }, // { label: "情报来源", prop: "cjlx", showSolt: true },
{ label: "转线索时间", prop: "zxssj" }, { label: "转线索时间", prop: "zxssj",width:190 },
{ label: "情报内容", prop: "qbnr" }, { label: "情报内容", prop: "qbnr",width:190 },
{ label: "所属部门", prop: "ssbm" }, { label: "所属部门", prop: "ssbm" },
] ]
}); });
@ -104,16 +105,9 @@ const queryFrom = ref({});
// 搜索 // 搜索
const onSearch = (val) => { const onSearch = (val) => {
const { lrkssj, zxkssj } = val queryFrom.value = { ...val }
const promes = { queryFrom.value.startTime = val.times ? val.times[0] : ''
...val, queryFrom.value.endTime = val.times ? val.times[1] : ''
...pageData.pageConfiger,
lrkssj: lrkssj ? lrkssj[0] : '',
lrjssj: lrkssj ? lrkssj[1] : '',
zxkssj: zxkssj ? zxkssj[0] : '',
zxjssj: zxkssj ? zxkssj[1] : '',
}
queryFrom.value = { ...promes }
pageData.pageConfiger.pageCurrent = 1; pageData.pageConfiger.pageCurrent = 1;
getList() getList()
} }
@ -131,6 +125,7 @@ const changeSize = (val) => {
const getList = () => { const getList = () => {
pageData.tableConfiger.loading = true; pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value }; let data = { ...pageData.pageConfiger, ...queryFrom.value };
delete data.times;
xxcjZxsSelectPage(data).then(res => { xxcjZxsSelectPage(data).then(res => {
pageData.tableData = res.records || []; pageData.tableData = res.records || [];
pageData.total = res.total; pageData.total = res.total;

View File

@ -0,0 +1,265 @@
<template>
<div class="items-container">
<el-card class="item-card">
<template #header>
<div class="card-header">
<span class="card-title">考核详情</span>
</div>
</template>
<div class="item-grid">
<!-- <div class="item-row">
<div class="item-col">
<span class="item-label">研判分数</span>
<span class="item-value">{{ row.ypfs || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">采集分数</span>
<span class="item-value">{{ row.cjfs || 0 }}</span>
</div>
</div> -->
<div class="item-section">
<h4>分数详情</h4>
<div class="item-grid">
<div class="item-col">
<span class="item-label">研判分数</span>
<span class="item-value">{{ row.ypfs || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">采集分数</span>
<span class="item-value">{{ row.cjfs || 0 }}</span>
</div>
</div>
</div>
<div class="item-section">
<h4>七类人员</h4>
<div class="item-grid">
<div class="item-col">
<span class="item-label">总数</span>
<span class="item-value">{{ row.qlryZs || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收数</span>
<span class="item-value">{{ row.qlryQss || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">反馈数</span>
<span class="item-value">{{ row.qlryFks || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收率</span>
<span class="item-value">{{ (row.qlryQsl || 0) * 100 }}%</span>
</div>
<div class="item-col">
<span class="item-label">反馈率</span>
<span class="item-value">{{ (row.qlryFkl || 0) * 100 }}%</span>
</div>
</div>
</div>
<div class="item-section">
<h4>人像预警</h4>
<div class="item-grid">
<div class="item-col">
<span class="item-label">总数</span>
<span class="item-value">{{ row.rxyjZs || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收数</span>
<span class="item-value">{{ row.rxyjQss || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">反馈数</span>
<span class="item-value">{{ row.rxyjFks || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收率</span>
<span class="item-value">{{ (row.rxyjQsl || 0) * 100 }}%</span>
</div>
<div class="item-col">
<span class="item-label">反馈率</span>
<span class="item-value">{{ (row.rxyjFkl || 0) * 100 }}%</span>
</div>
</div>
</div>
<div class="item-section">
<h4>车辆预警</h4>
<div class="item-grid">
<div class="item-col">
<span class="item-label">总数</span>
<span class="item-value">{{ row.clyjZs || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收数</span>
<span class="item-value">{{ row.clyjQss || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">反馈数</span>
<span class="item-value">{{ row.clyjFks || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收率</span>
<span class="item-value">{{ (row.clyjQsl || 0) * 100 }}%</span>
</div>
<div class="item-col">
<span class="item-label">反馈率</span>
<span class="item-value">{{ (row.clyjFkl || 0) * 100 }}%</span>
</div>
</div>
</div>
<div class="item-section">
<h4>布控预警</h4>
<div class="item-grid">
<div class="item-col">
<span class="item-label">总数</span>
<span class="item-value">{{ row.bkyjZs || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收数</span>
<span class="item-value">{{ row.bkyjQss || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">反馈数</span>
<span class="item-value">{{ row.bkyjFks || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收率</span>
<span class="item-value">{{ (row.bkyjQsl || 0) * 100 }}%</span>
</div>
<div class="item-col">
<span class="item-label">反馈率</span>
<span class="item-value">{{ (row.bkyjFkl || 0) * 100 }}%</span>
</div>
</div>
</div>
<div class="item-section">
<h4>政保预警</h4>
<div class="item-grid">
<div class="item-col">
<span class="item-label">总数</span>
<span class="item-value">{{ row.zbyjZs || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收数</span>
<span class="item-value">{{ row.zbyjQss || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">反馈数</span>
<span class="item-value">{{ row.zbyjFks || 0 }}</span>
</div>
<div class="item-col">
<span class="item-label">签收率</span>
<span class="item-value">{{ (row.zbyjQsl || 0) * 100 }}%</span>
</div>
<div class="item-col">
<span class="item-label">反馈率</span>
<span class="item-value">{{ (row.zbyjFkl || 0) * 100 }}%</span>
</div>
</div>
</div>
<!-- <div class="item-row">
<div class="item-col">
<span class="item-label">更新时间</span>
<span class="item-value">{{ row.gxsj || '-' }}</span>
</div>
</div> -->
</div>
</el-card>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
row: {
type: Object,
default: () => ({})
}
});
</script>
<style lang="scss" scoped>
.items-container {
width: 100%;
padding: 10px;
height: 40vh;
overflow: auto;
}
.item-card {
margin-bottom: 10px;
background-color: #f0f0f0;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
.card-title {
color: #000;
}
}
.item-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 20px;
}
.item-section {
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px solid #f0f0f0;
h4 {
margin-bottom: 15px;
color: #303133;
font-size: 14px;
font-weight: bold;
}
}
.item-row {
display: flex;
flex-wrap: wrap;
gap: 20px;
margin-bottom: 15px;
}
.item-col {
display: flex;
align-items: center;
gap: 8px;
}
.item-label {
color: #606266;
font-size: 13px;
white-space: nowrap;
}
.item-value {
color: #303133;
font-size: 13px;
font-weight: 500;
}
// 响应式调整
@media (max-width: 768px) {
.item-grid {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.item-row {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
}
</style>

View File

@ -0,0 +1,153 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">工作考核{{ title }} </span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-if="title != '详情'">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules" :disabled="title == '详情'">
<template #bkyj>
<el-divider content-position="left"><span style="color: blue;">布控预警</span></el-divider>
</template>
<template #clyj>
<el-divider content-position="left"><span style="color: blue;">车辆预警</span></el-divider>
</template>
<template #qlry>
<el-divider content-position="left"><span style="color: blue;">7类重点人员预警</span></el-divider>
</template>
<template #rxyj>
<el-divider content-position="left"><span style="color: blue;">人像预警</span></el-divider>
</template>
<template #zbyj>
<el-divider content-position="left"><span style="color: blue;">政保预警</span></el-divider>
</template>
<template #fs>
<el-divider content-position="left"><span style="color: blue;">考核分数</span></el-divider>
</template>
</FormMessage>
</div>
</div>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qcckGet, qcckPost,qcckPut } from "@/api/qcckApi.js";
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, } from "vue";
const emit = defineEmits(["updateDate"]);
const props = defineProps({
dic: Object
});
const listQuery = ref({
cjfs: 0,
ypfs: 0,
bkyjFkl: 0,
bkyjQsl: 0,
clyjFkl: 0,
clyjQsl: 0,
qlryFkl: 0,
qlryQsl: 0,
rxyjFkl: 0,
rxyjQsl: 0,
zbyjFkl: 0,
zbyjQsl: 0,
}); //表单
const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗
const formData = ref([
{ label: "考核部门", prop: "ssbmdm", depMc: "ssbm", type: "department" },
{ label: "考核开始日期", prop: "ksrq", type: "date" },
{ label: "考核结束日期", prop: "jsrq", type: "date" },
{ label: "考核描述", prop: "khzbms", type: "textarea", width: "100%" },
{ prop: "fs", type: "slot", width: "100%" },
{ label: "采集分数", prop: "cjfs", type: "number", min: 0, max: 100, step: 1 },
{ label: "研判分数", prop: "ypfs", type: "number", min: 0, max: 100, step: 1 },
{ prop: "bkyj", type: "slot", width: "100%" },
{ label: "布控预警反馈率", prop: "bkyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
{ label: "布控预警签收率", prop: "bkyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
{ prop: "clyj", type: "slot", width: "100%" },
{ label: "车辆预警反馈率", prop: "clyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
{ label: "车辆预警签收率", prop: "clyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
{ prop: "qlry", type: "slot", width: "100%" },
{ label: "7类重点人员反馈率", prop: "qlryFkl", type: "number", min: 0, max: 100, step: 0.01 },
{ label: "7类重点人员签收率", prop: "qlryQsl", type: "number", min: 0, max: 100, step: 0.01 },
{ prop: "rxyj", type: "slot", width: "100%" },
{ label: "人像预警反馈率", prop: "rxyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
{ label: "人像预警签收率", prop: "rxyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
{ prop: "zbyj", type: "slot", width: "100%" },
{ label: "政保预警反馈率", prop: "zbyjFkl", type: "number", min: 0, max: 100, step: 0.01 },
{ label: "政保预警签收率", prop: "zbyjQsl", type: "number", min: 0, max: 100, step: 0.01 },
]);
const loading = ref(false);
const elform = ref();
const title = ref("");
const rules = reactive({
ssbmdm: [{ required: true, message: "请选择考核部门", trigger: "change" }],
ksrq: [{ required: true, message: "请选择考核开始日期", trigger: "change" }],
jsrq: [{ required: true, message: "请选择考核结束日期", trigger: "change" }],
khzbms: [{ required: true, message: "请输入考核描述", trigger: "blur" }],
// ryXm: [{ required: true, message: "请输入人员姓名", trigger: "blur" }],
});
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = type == "add" ? "新增" : type == "detail" ? "详情" : "编辑";
if (row) getDataById(row.id);
};
// 根据id查询详情
const getDataById = (id) => {
qcckGet({ id }, `/mosty-gsxt/khgl/${id}`).then((res) => {
listQuery.value = res;
});
};
// 提交
const submit = () => {
elform.value.submit((data) => {
let url = title.value == "新增" ? "/mosty-gsxt/khgl/addEntity" : "/mosty-gsxt/khgl/editEntity";
let params = { ...data };
console.log(params);
loading.value = true;
if (title.value == "新增") {
qcckPost(params, url).then(() => {
loading.value = false;
proxy.$message({ type: "success", message: title.value + "成功" });
emit("updateDate");
close();
}).catch(() => { loading.value = false; });
} else {
qcckPut(params, url).then(() => {
loading.value = false;
proxy.$message({ type: "success", message: title.value + "成功" });
emit("updateDate");
close();
}).catch(() => { loading.value = false; });
}
});
};
// 关闭
const close = () => {
listQuery.value = {};
dialogForm.value = false;
loading.value = false;
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-textarea__inner {
height: 18.5em !important;
}
</style>

View File

@ -0,0 +1,171 @@
<template>
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left>
<el-button size="small" type="primary" @click="addEdit('add', '')">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">新增</span>
</el-button>
</template>
</PageTitle>
<!-- 表格 -->
<div class="tabBox">
<!-- <MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"> -->
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
expand :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #expand="{ props }">
<div style="max-width: 100%">
<Items :row="props || {}" />
</div>
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link size="small" type="success" @click="addEdit('edit', row)">编辑</el-link>
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
<!-- 详情 -->
<DetailForm v-if="show" @updateDate="getList" ref="detailDiloag"
:dic="{ D_BZ_WHCD, D_BZ_MZ, D_BZ_XB, D_BZ_ZZMM, D_GS_RLQB_JCQK }" />
</div>
</template>
<script setup>
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import DetailForm from "./components/addForm.vue";
import Items from "./components/Items.vue";
import { qcckGet, qcckPost, qcckDelete} from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
const { proxy } = getCurrentInstance();
const { D_GS_RLQB_JCQK, D_BZ_WHCD, D_BZ_MZ, D_BZ_XB, D_BZ_ZZMM } = proxy.$dict("D_GS_RLQB_JCQK", "D_BZ_WHCD", "D_BZ_MZ", "D_BZ_XB", "D_BZ_ZZMM"); //获取字典数据
const detailDiloag = ref();
const searchBox = ref(); //搜索框
const show = ref(false);
const searchConfiger = ref([
{ label: "所属部门", prop: "ssbmdm", placeholder: "请选择所属部门", showType: "department" },
{ label: "时间", prop: "startTime", placeholder: "请选择时间", showType: "datetimerange" }
]);
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
},
controlsWidth: 200,
tableColumn: [
// { label: "布控预警反馈率", prop: "bkyjFkl" },
// { label: "布控预警签收率", prop: "bkyjQsl" },
// { label: "采集分数", prop: "cjfs" },
// { label: "车辆预警反馈率", prop: "clyjFkl" },
// { label: "车辆预警签收率", prop: "clyjQsl"},
// { label: "7类重点人员反馈率", prop: "qlryFkl" },
// { label: "7类重点人员签收率", prop: "qlryQsl" },
// { label: "人像预警反馈率", prop: "rxyjFkl" },
// { label: "人像预警签收率", prop: "rxyjQsl" },
// { label: "政保预警反馈率", prop: "zbyjFkl" },
// { label: "政保预警签收率", prop: "zbyjQsl" },
// { label: "采集分数", prop: "cjfs" },
// { label: "研判分数", prop: "ypfs" },
{ label: "考核开始日期", prop: "ksrq" },
{ label: "考核结束日期", prop: "jsrq" },
{ label: "考核年份", prop: "khnf" },
{ label: "所属部门", prop: "ssbm" },
]
});
const queryFrom = ref({});
onMounted(() => {
getList();
tabHeightFn();
});
// 搜索
const onSearch = (val) => {
queryFrom.value = {
...val,
startTime: val.startTime ? val.startTime[0] : "",
endTime: val.startTime ? val.startTime[0] : ""
};
pageData.pageConfiger.pageCurrent = 1;
getList();
};
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value };
qcckGet(data, "/mosty-gsxt/khgl/getPageList").then((res) => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
}).catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 删除
const deleteRow = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
qcckDelete({ ids:[id]}, "/mosty-gsxt/khgl/deleteEntity").then(() => {
proxy.$message({ type: "success", message: "删除成功" });
getList();
});
})
};
// 详情
const addEdit = (type, row) => {
show.value = true;
nextTick(() => {
detailDiloag.value.init(type, row);
});
};
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>

View File

@ -0,0 +1,561 @@
<template>
<div class="dialog">
<div class="form-container">
<div class="form-content" v-loading="loading">
<!-- <div class="form_cnt"> -->
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
<!-- <template #jbxx>
<div>
<h3 class="tags-title">报送情况</h3>
<div style="display: flex;justify-content:space-between;width: 200%;">
<div>录入人{{ userName }}</div>
<div>录入单位{{ userInfo.deptName }}</div>
<div>本年度报送信息量{{ tjcll.cnl || 0 }}</div>
<div>采纳量{{ tjcll.sbsl || 0 }}</div>
</div>
</div>
</template> -->
<template #shzt>
<div v-if="disabled">
<h3 class="tags-title">审核状态</h3>
<div style="display: flex;justify-content:space-between;width: 200%;">
<div style="display: flex;">
市审核状态
<DictTag v-model:value="listQuery.sldshzt" :options="D_BZ_SSSHZT" :tag="false" />
</div>
<div style="display: flex;">
县审核状态
<DictTag v-model:value="listQuery.xldshzt" :options="D_BZ_SSSHZT" :tag="false" />
</div>
</div>
</div>
</template>
</FormMessage>
<!-- </div> -->
<div class="tags-section" v-if="disabled">
<h3 class="tags-title">关注部门</h3>
<div class="tags-container">
<div v-for="(tag, index) in listQuery.gzbmList" :key="tag.id || index" class="tag-item">
<div class="tag-content">
{{ tag.ssbm }}
</div>
</div>
<span v-if="!listQuery.gzbmList || listQuery.gzbmList.length === 0" class="no-tags">
暂无标签
</span>
</div>
</div>
<div class="tags-section" v-if="disabled">
<h3 class="tags-title">关联标签</h3>
<div class="tags-container">
<div v-for="(tag, index) in listQuery.glbqList" :key="tag.id || index" class="tag-item">
<div class="tag-content">
{{ tag.bqmc }}
</div>
</div>
<span v-if="!listQuery.glbqList || listQuery.glbqList.length === 0" class="no-tags">
暂无标签
</span>
</div>
</div>
<div class="tags-section" v-if="disabled">
<h3 class="tags-title">续报信息</h3>
<div class="list-container">
<div v-for="(item, index) in dataList.xb" :key="item.id || index" class="list-item">
<div class="list-content">
{{ item.bcnr }}
</div>
</div>
<span v-if="!dataList.xb || dataList.xb.length === 0" class="no-tags">
暂无续报信息
</span>
</div>
</div>
<div class="tags-section" v-if="disabled">
<h3 class="tags-title">补充信息</h3>
<div class="list-container">
<div v-for="(item, index) in dataList.bc" :key="item.id || index" class="list-item">
<div class="list-content">
{{ item.bcnr }}
</div>
</div>
<span v-if="!dataList.bc || dataList.bc.length === 0" class="no-tags">
暂无补充信息
</span>
</div>
</div>
</div>
<div class="ml50 mr50 timeline-container" v-if="disabled">
<div class="timeline-title">信息流程展示</div>
<el-timeline class="timeline-full-width">
<el-timeline-item :timestamp="item.czsj" placement="top" v-for="(item, index) in lcList" :key="index">
<el-card class="process-card">
<div class="process-info">
<div class="info-label">处置人</div>
<div class="info-value">{{ item.czrxm || '未记录' }}</div>
</div>
<div class="process-info">
<div class="info-label">处置结果</div>
<div class="info-value">
<DictTag :tag="false" :value="item.czzt" :options="D_BZ_LCZT" />
</div>
</div>
</el-card>
</el-timeline-item>
</el-timeline>
<MOSTY.Empty :show="lcList.length == 0" :imgSize="100"></MOSTY.Empty>
</div>
</div>
</div>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { xxcjSelectByid, xxcjSelectCzlcList, xxcjSelectListBc } from "@/api/xxcj.js"
import { ref, defineExpose, onMounted, defineEmits, watch, getCurrentInstance } from "vue"
import { getItem } from '@//utils/storage.js'
import { useRoute, useRouter } from 'vue-router'
import * as MOSTY from "@/components/MyComponents/index";
const { proxy } = getCurrentInstance()
const {D_BZ_SSSHZT,D_BZ_LCZT} =proxy.$dict('D_BZ_SSSHZT','D_BZ_LCZT')
const route=useRoute()
const emit = defineEmits(["getList"]);
const props = defineProps({
dict: Object,
titleData: {
type: String,
default: ""
},
showBc: {
type: Boolean,
default: false
}
});
const loading = ref(false)
const formData = ref([
{ label: "情报标题", prop: "qbmc", type: "input", width: '45%' },
{ label: "情报内容", prop: "qbnr", type: "textarea", width: '100%', rows: 100 },
{ label: "附件上传", prop: "fjdz", type: "upload", width: '100%', isImg: false },
{ label: "", prop: "jbxx", type: "slot", width: '100%', },
{ label: "", prop: "shzt", type: "slot", width: '100%' },
]);
const rules = ref({
qbmc: [{ required: true, message: "请输入情报标题", trigger: "blur" }],
qbnr: [{ required: true, message: "请输入情报内容", trigger: "blur" }],
bcnr: [{ required: true, message: "请输入续报内容", trigger: "blur" }],
})
const fjdz = ref()
const listQuery = ref({}); //表单
const disabled = ref(false)
/** 类型 add 新增 info 详情 edit 编辑 followUpReport 续报*/
onMounted(() => {
init()
})
// 初始化数据
const init = () => {
const id= route.query.id
disabled.value = true
fjdz.value = []
getqbcjPldb(id)
getxxcjSelectListBc(id, '01')
getxxcjSelectListBc(id, '02')
getDataById(id);
};
// 根据id查询详情
const getDataById = (id) => {
xxcjSelectByid({ id }).then((res) => {
lcList.value = res.czlcList || []
listQuery.value = res;
listQuery.value.fjdz = res.fjdz ? res.fjdz?.split(",") : []
});
};
const lcList = ref([])
const getqbcjPldb = (id) => {
xxcjSelectCzlcList({ qbid: id }).then(res => {
lcList.value = res || []
})
.catch(() => {
})
}
//
const dataList = ref({
xb: [],
bc: [],
})
const getxxcjSelectListBc = (id, lx) => {
xxcjSelectListBc({ qbid: id, czlx: lx }).then(res => {
if (lx == '01') {
dataList.value.xb = res || []
} else {
dataList.value.bc = res || []
}
})
}
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
.boxlist {
width: 99%;
height: 225px;
margin-top: 10px;
overflow: hidden;
}
::v-deep .avatar-uploader {
display: flex;
align-items: center;
}
::v-deep .el-upload-list {
margin-left: 20px;
display: flex;
align-items: center;
}
::v-deep .el-upload-list__item-name .el-icon {
top: 3px;
}
.form_cnt {
// width: 75%;
flex: 1;
}
.person {
padding-left: 20px;
width: 25%;
// height: 100vh;
}
/* 补充信息样式 */
.supplement-title {
font-size: 14px;
font-weight: 500;
color: #333;
margin: 16px 0 10px 0;
padding-left: 5px;
border-left: 3px solid #24b6dd;
}
.supplement-list {
margin-left: 5px;
}
.supplement-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
background-color: #f5f7fa;
border: 1px solid #e4e7ed;
border-radius: 4px;
margin-bottom: 8px;
margin-right: 10px;
transition: all 0.3s ease;
}
.supplement-item:hover {
background-color: #ecf5ff;
border-color: #c6e2ff;
}
.supplement-content {
flex: 1;
font-size: 14px;
color: #606266;
line-height: 1.5;
}
.supplement-actions {
display: flex;
gap: 12px;
}
.action-icon {
// font-size: 24px;
cursor: pointer;
transition: all 0.3s ease;
}
.edit-icon {
color: #24b6dd;
}
.edit-icon:hover {
color: #409eff;
transform: scale(1.1);
}
.delete-icon {
color: #f56c6c;
}
.delete-icon:hover {
color: #f78989;
transform: scale(1.1);
}
/* 时间线标题样式 */
.timeline-title {
font-size: 16px;
font-weight: 600;
color: #303133;
padding: 12px 16px;
margin-bottom: 10px;
background-color: #f5f7fa;
border-bottom: 1px solid #ebeef5;
border-radius: 4px 4px 0 0;
}
/* 时间线样式优化 */
.el-timeline {
margin-top: 20px;
}
/* 处置流程卡片样式 */
.process-card {
border: none;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
margin-bottom: 16px;
border-left: 3px solid #409EFF;
}
.process-card:hover {
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.12);
transform: translateY(-2px);
}
/* 卡片内部信息样式 */
.process-info {
display: flex;
align-items: flex-start;
margin-bottom: 12px;
flex-wrap: wrap;
}
.process-info:last-child {
margin-bottom: 0;
}
.info-label {
font-size: 14px;
font-weight: 600;
color: #409EFF;
margin-right: 8px;
min-width: 65px;
}
.info-value {
font-size: 14px;
color: #606266;
line-height: 1.6;
flex: 1;
word-break: break-word;
}
/* 时间戳样式 */
.el-timeline-item__timestamp {
font-size: 13px;
color: #909399;
margin-bottom: 8px;
}
/* 时间线节点样式 */
.el-timeline-item__node {
background-color: #409EFF;
}
::v-deep .el-textarea__inner {
height: 50vh !important;
}
/* 容器类样式 */
.form-container {
display: flex;
width: 100%;
}
.form-content {
// display: flex;
width: 80%;
}
.timeline-container {
border: 1px solid #ebeef5;
flex: 1;
margin: 0 10px;
}
/* 时间线宽度 */
.timeline-full-width {
width: 100%;
}
/* 标签区域样式 */
.tags-section {
margin-top: 20px;
}
/* 标签标题样式 */
.tags-title {
font-size: 14px;
font-weight: 600;
color: #303133;
margin-bottom: 8px;
padding-left: 5px;
border-left: 3px solid #409EFF;
}
/* 标签容器样式 */
.tags-container {
padding: 12px;
background-color: #f5f7fa;
border-radius: 4px;
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: center;
}
/* 标签项目样式 */
.tag-item {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 10px;
background-color: #ecf5ff;
border-radius: 4px;
border: 1px solid #d9ecff;
transition: all 0.3s ease;
}
/* 标签项目悬停效果 */
.tag-item:hover {
background-color: #e6f7ff;
border-color: #91d5ff;
box-shadow: 0 2px 8px rgba(0, 123, 255, 0.15);
}
/* 标签内容样式 */
.tag-content {
margin: 0;
font-size: 14px;
color: #303133;
font-weight: 500;
}
/* 标签操作按钮样式 */
.tag-actions {
display: flex;
// align-items: flex-start;
gap: 8px;
}
/* 操作图标样式 */
.action-icon {
font-size: 18px;
cursor: pointer;
transition: all 0.3s ease;
padding: 6px 8px;
border-radius: 4px;
display: inline-flex;
align-items: center;
justify-content: center;
}
/* 编辑图标样式 */
.edit-icon {
color: #409EFF;
background-color: #ecf5ff;
}
.edit-icon:hover {
color: #66B1FF;
background-color: #e6f7ff;
transform: scale(1.05);
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.2);
}
/* 列表容器样式 */
.list-container {
padding: 12px;
background-color: #f5f7fa;
border-radius: 4px;
}
/* 列表项样式 */
.list-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 12px;
background-color: #ffffff;
border-radius: 4px;
margin-bottom: 8px;
border: 1px solid #e4e7ed;
transition: all 0.3s ease;
}
/* 列表项悬停效果 */
.list-item:hover {
background-color: #f5f7fa;
border-color: #dcdfe6;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
/* 列表内容样式 */
.list-content {
margin: 0;
font-size: 14px;
color: #303133;
font-weight: 500;
}
/* 删除图标样式 */
.delete-icon {
color: #F56C6C;
background-color: #fef0f0;
}
.delete-icon:hover {
color: #F78989;
background-color: #fde2e2;
transform: scale(1.05);
box-shadow: 0 2px 4px rgba(245, 108, 108, 0.2);
}
/* 无标签提示样式 */
.no-tags {
color: #909399;
font-size: 14px;
font-style: italic;
}
</style>

View File

@ -27,10 +27,13 @@
<DictTag :tag="false" :value="row.sldshzt" :options="D_BZ_SSSHZT" /> <DictTag :tag="false" :value="row.sldshzt" :options="D_BZ_SSSHZT" />
</template> </template>
<template #controls="{ row }"> <template #controls="{ row }">
<el-link size="small" type="danger" @click="openDoingLogin(row)" <el-link size="small" type="danger" @click="openDoingLogin(row)"
v-if="row.sldshzt == '01' && getRole() == '02'">审批</el-link> v-if="row.sldshzt == '01' && getRole() == '02'">审批</el-link>
<el-link size="small" type="danger" @click="openDoingLogin(row)" <el-link size="small" type="danger" @click="openDoingLogin(row)"
v-if="row.xldshzt == '01' && getRole() == '01'">审批</el-link> v-if="row.xldshzt == '01' && getRole() == '01'">审批</el-link>
<el-link size="small" type="warning" @click="createProcess(row)"
v-if="row.sldshzt == '02' && getRole() == '02'">送审</el-link>
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link> <el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
</template> </template>
</MyTable> </MyTable>
@ -43,6 +46,8 @@
<AddForm ref="detailDiloag" @getList="getList" :dict="{ D_BZ_LCZT, D_BZ_SSSHZT }" /> <AddForm ref="detailDiloag" @getList="getList" :dict="{ D_BZ_LCZT, D_BZ_SSSHZT }" />
</div> </div>
<Doinglogin v-model="doingloginModel" :dataModel="dataModel" :dict="{ D_BZ_SSSHZT }" @getList="getList" /> <Doinglogin v-model="doingloginModel" :dataModel="dataModel" :dict="{ D_BZ_SSSHZT }" @getList="getList" />
<SubmissionProcess v-model="showSp" :data="rowData" :userData="{ ajmc: '情报审批', flowType: 'QBSP', modelName: '情报' }"
:path="fixedValue" @getList="getList" />
</template> </template>
<script setup> <script setup>
@ -51,6 +56,7 @@ import Doinglogin from "./components/doinglogin.vue";
import Pages from "@/components/aboutTable/Pages.vue"; import Pages from "@/components/aboutTable/Pages.vue";
import Searchs from "@/components/aboutTable/Search.vue"; import Searchs from "@/components/aboutTable/Search.vue";
import AddForm from "./components/addForm.vue"; import AddForm from "./components/addForm.vue";
import SubmissionProcess from '@/components/flowPath/submissionProcess.vue'
import { xxcjSelectDshPage } from '@/api/xxcj.js' import { xxcjSelectDshPage } from '@/api/xxcj.js'
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import { getItem } from "@/utils/storage"; import { getItem } from "@/utils/storage";
@ -148,13 +154,25 @@ const openDoingLogin = (row) => {
dataModel.value = row dataModel.value = row
doingloginModel.value = true doingloginModel.value = true
} }
const detailDiloag=ref() const detailDiloag = ref()
const addEdit = (type, row) => { const addEdit = (type, row) => {
setTimeout(() => { setTimeout(() => {
detailDiloag.value.init(type, row); detailDiloag.value.init(type, row);
}, 500) }, 500)
}; };
// 固定值
const fixedValue = {
clueVerification: 'Spdloyment',
byMeansOf: '/qbcj/callback',
nobyMeansOf: '/qbcj/callback',
recycle: '/qbcj/callback',
}
const showSp = ref(false);
const rowData = ref()
const createProcess = (row) => {
showSp.value = true;
rowData.value = row
}
// 表格高度计算 // 表格高度计算
const tabHeightFn = () => { const tabHeightFn = () => {

View File

@ -177,54 +177,36 @@ const previewFile = (item) => {
window.open(item.wjdz); window.open(item.wjdz);
} }
const downloadFile = async (item) => { const downloadFile = async (item) => {
console.log(item);
try { try {
const dataList =JSON.parse(item.wjdz) const dataList =JSON.parse(item.wjdz)
if (dataList.length === 0) { if (dataList.length === 0) return proxy.$message.warning('没有文件可下载');
proxy.$message.warning('没有文件可下载');
return;
}
console.log(dataList);
const downloadCount = dataList.length; const downloadCount = dataList.length;
let successCount = 0; let successCount = 0;
let failCount = 0; let failCount = 0;
proxy.$message.info(`开始下载${downloadCount}个文件...`); proxy.$message.info(`开始下载${downloadCount}个文件...`);
// 并行下载所有文件
const downloadPromises = dataList.map(async (fileData, index) => { const downloadPromises = dataList.map(async (fileData, index) => {
try { try {
// fileData.url = "http://47.108.232.77:9000/image/2025-01-06/081102a5418e4146beea277d18018e07.jpeg";
// 使用fetch获取文件内容 // 使用fetch获取文件内容
const response = await fetch(fileData.url); const downloadUrl = fileData.url.replace(/^https?:\/\/[^/]+/, '/zyminio');
if (!response.ok) { const response = await fetch(downloadUrl);
throw new Error('文件下载失败'); if (!response.ok) throw new Error('文件下载失败');
}
// 将响应转换为Blob对象 // 将响应转换为Blob对象
const blob = await response.blob(); const blob = await response.blob();
// 创建下载链接 // 创建下载链接
const downloadLink = document.createElement('a'); const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob); downloadLink.href = URL.createObjectURL(blob);
// 设置下载文件的名称,避免冲突 // 设置下载文件的名称,避免冲突
const fileName = dataList.length > 1 const fileName = dataList.length > 1 ? `${item.wjmc}_${index + 1}` : item.wjmc;
? `${item.wjmc}_${index + 1}`
: item.wjmc;
downloadLink.download = fileName; downloadLink.download = fileName;
// 触发下载 // 触发下载
document.body.appendChild(downloadLink); document.body.appendChild(downloadLink);
downloadLink.click(); downloadLink.click();
// 清理 // 清理
setTimeout(() => { setTimeout(() => {
document.body.removeChild(downloadLink); document.body.removeChild(downloadLink);
URL.revokeObjectURL(downloadLink.href); URL.revokeObjectURL(downloadLink.href);
}, 100); }, 100);
successCount++; successCount++;
} catch (error) { } catch (error) {
console.error(`文件${index + 1}下载失败:`, error); console.error(`文件${index + 1}下载失败:`, error);

View File

@ -1,25 +1,27 @@
<template> <template>
<div> <div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10"> <div ref="searchBox" class="mt10">
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" /> <Search :searchArr="searchConfiger" @submit="onSearch" />
</div> </div>
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5"> <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left> <template #left>
<el-button size="small" type="primary" @click="getDataById('add', '')"> <el-button size="small" type="primary" @click="getDataById('add', '')">
<el-icon style="vertical-align: middle"> <el-icon style="vertical-align: middle"><CirclePlus /></el-icon>
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">新增</span> <span style="vertical-align: middle">新增</span>
</el-button> </el-button>
</template> </template>
</PageTitle> </PageTitle>
<!-- 表格 --> <!-- 表格 -->
<div class="tabBox"> <div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight" <MyTable
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth" :tableData="pageData.tableData"
@chooseData="chooseData"> :tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
@chooseData="chooseData"
>
<template #wjdx="{ row }"> <template #wjdx="{ row }">
{{ row.wjdx }}MB {{ row.wjdx }}MB
</template> </template>
@ -30,16 +32,17 @@
<template #controls="{ row }"> <template #controls="{ row }">
<el-link size="small" type="primary" @click="getDataById('edit', row)">修改</el-link> <el-link size="small" type="primary" @click="getDataById('edit', row)">修改</el-link>
<el-link size="small" type="primary" @click="getDataById('detail', row)">详情</el-link> <el-link size="small" type="primary" @click="getDataById('detail', row)">详情</el-link>
<el-link size="small" type="primary" @click="previewFile(row)" <el-link size="small" type="primary" @click="previewFile(row)" v-if="row.wjlx == '.png' || row.wjlx == '.jpg' || row.wjlx == '.jpeg'">预览</el-link>
v-if="row.wjlx == '.png' || row.wjlx == '.jpg' || row.wjlx == '.jpeg'">预览</el-link>
<el-link size="small" type="primary" @click="downloadFile(row)">下载</el-link> <el-link size="small" type="primary" @click="downloadFile(row)">下载</el-link>
<el-link size="small" type="danger" @click="deleteFile(row)">删除</el-link> <el-link size="small" type="danger" @click="deleteFile(row)">删除</el-link>
</template> </template>
</MyTable> </MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{ <Pages
...pageData.pageConfiger, @changeNo="changeNo"
total: pageData.total @changeSize="changeSize"
}"></Pages> :tableHeight="pageData.tableHeight"
:pageConfiger="{ ...pageData.pageConfiger, total: pageData.total }"
/>
</div> </div>
</div> </div>
<AddForm ref="addForm" @getList="getList" /> <AddForm ref="addForm" @getList="getList" />
@ -51,47 +54,22 @@ import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue"; import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue"; import Search from "@/components/aboutTable/Search.vue";
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { qbcjZxsSelectPage } from "@/api/qbcj.js"; import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
import { getItem } from '@//utils/storage.js' import { getItem } from '@//utils/storage.js'
import { deleteWjZzzAddEntity, getWjZzzAddEntity } from '@//api/qbcj.js' import { deleteWjZzzAddEntity, getWjZzzAddEntity } from '@//api/qbcj.js'
import AddForm from "./components/addForm.vue"; import AddForm from "./components/addForm.vue";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
// const { D_BZ_CJLX, D_GS_XS_LX } = proxy.$dict("D_BZ_CJLX", "D_GS_XS_LX"); //获取字典数据
const detailDiloag = ref(); const detailDiloag = ref();
const searchBox = ref(); //搜索框 const searchBox = ref(); //搜索框
const ids = ref([]) const ids = ref([])
const tableList = ref([]); const tableList = ref([]);
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
getRouter()
tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', {
id: route.query.id
});
return
}
getList()
});
const chooseData = (val) => {
ids.value = val.map(item => {
return item.id
})
tableList.value = val
}
const qxkz = reactive({ const qxkz = reactive({
deptBizType: "", deptBizType: "",
deptLevel: "" deptLevel: ""
}) })
const searchConfiger = ref([ const searchConfiger = ref([
{ label: "文件名称", prop: 'wjmc', placeholder: "请输入文件名称", showType: "input" }, { label: "文件名称", prop: 'wjmc', placeholder: "请输入文件名称", showType: "input" },
// { label: "情报来源", prop: 'cjLx', placeholder: "请选择情报来源", showType: "select", options: D_BZ_CJLX },
// { label: "来源单位", prop: 'ssbmdm', placeholder: "请选择来源单位", showType: "department" }
]); ]);
const pageData = reactive({ const pageData = reactive({
@ -117,6 +95,26 @@ const pageData = reactive({
] ]
}); });
const queryFrom = ref({}); const queryFrom = ref({});
const addForm = ref(null)
const route = useRoute()
const routerMate = ref({})
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
qxkz.deptBizType = deptBizType
qxkz.deptLevel = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
routerMate.value = route.meta;
getList()
tabHeightFn()
if (route.query.id) return detailDiloag.value.init('edit', { id: route.query.id });
});
const chooseData = (val) => {
if(Array.isArray(val)){
ids.value = val.map(item => item.id)
tableList.value = val
}
}
// 搜索 // 搜索
const onSearch = (val) => { const onSearch = (val) => {
@ -162,67 +160,48 @@ const tabHeightFn = () => {
tabHeightFn(); tabHeightFn();
}; };
}; };
const route = useRoute()
const routerMate = ref({})
const getRouter = () => {
routerMate.value = route.meta
}
const addForm = ref(null)
const getDataById = (type, row) => { const getDataById = (type, row) => {
addForm.value.init(type, row, '01'); addForm.value.init(type, row, '01');
} }
const previewFile = (item) => { const previewFile = (item) => {
window.open(item.wjdz); window.open(item.wjdz);
} }
const downloadFile = async (item) => {
console.log(item);
try {
const dataList =JSON.parse(item.wjdz)
if (dataList.length === 0) {
proxy.$message.warning('没有文件可下载');
return;
}
console.log(dataList);
const downloadFile = async (item) => {
try {
const dataList = JSON.parse(item.wjdz)
if (dataList.length === 0) return proxy.$message.warning('没有文件可下载');
const downloadCount = dataList.length; const downloadCount = dataList.length;
let successCount = 0; let successCount = 0;
let failCount = 0; let failCount = 0;
proxy.$message.info(`开始下载${downloadCount}个文件...`); proxy.$message.info(`开始下载${downloadCount}个文件...`);
// 并行下载所有文件 // 并行下载所有文件
const downloadPromises = dataList.map(async (fileData, index) => { const downloadPromises = dataList.map(async (fileData, index) => {
try { try {
// fileData.url = "http://47.108.232.77:9000/image/2025-01-06/081102a5418e4146beea277d18018e07.jpeg";
// 使用fetch获取文件内容 // 使用fetch获取文件内容
const response = await fetch(fileData.url); const downloadUrl = fileData.url.replace(/^https?:\/\/[^/]+/, '/zyminio');
if (!response.ok) { const response = await fetch(downloadUrl);
throw new Error('文件下载失败'); if (!response.ok) throw new Error('文件下载失败');
}
// 将响应转换为Blob对象 // 将响应转换为Blob对象
const blob = await response.blob(); const blob = await response.blob();
// 创建下载链接 // 创建下载链接
const downloadLink = document.createElement('a'); const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob); downloadLink.href = URL.createObjectURL(blob);
// 设置下载文件的名称,避免冲突 // 设置下载文件的名称,避免冲突
const fileName = dataList.length > 1 const fileName = dataList.length > 1 ? `${item.wjmc}_${index + 1}` : item.wjmc;
? `${item.wjmc}_${index + 1}`
: item.wjmc;
downloadLink.download = fileName; downloadLink.download = fileName;
// 触发下载 // 触发下载
document.body.appendChild(downloadLink); document.body.appendChild(downloadLink);
downloadLink.click(); downloadLink.click();
// 清理 // 清理
setTimeout(() => { setTimeout(() => {
document.body.removeChild(downloadLink); document.body.removeChild(downloadLink);
URL.revokeObjectURL(downloadLink.href); URL.revokeObjectURL(downloadLink.href);
}, 100); }, 100);
successCount++; successCount++;
} catch (error) { } catch (error) {
console.error(`文件${index + 1}下载失败:`, error); console.error(`文件${index + 1}下载失败:`, error);
@ -242,16 +221,12 @@ console.log(dataList);
proxy.$message.warning(`成功下载${successCount}个文件,失败${failCount}个文件`); proxy.$message.warning(`成功下载${successCount}个文件,失败${failCount}个文件`);
} }
} catch (error) { } catch (error) {
console.error('文件下载失败:', error);
proxy.$message.error('文件下载失败,请稍后重试'); proxy.$message.error('文件下载失败,请稍后重试');
} }
} }
const deleteFile = (row) => { const deleteFile = (row) => {
proxy.$confirm('确定删除选中文件吗?', '提示', { proxy.$confirm('确定删除选中文件吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteWjZzzAddEntity({ ids: [row.id] }).then(res => { deleteWjZzzAddEntity({ ids: [row.id] }).then(res => {
proxy.$message.success('删除成功'); proxy.$message.success('删除成功');
getList(); getList();

View File

@ -11,17 +11,19 @@
<div class="form-content" v-loading="loading"> <div class="form-content" v-loading="loading">
<!-- <div class="form_cnt"> --> <!-- <div class="form_cnt"> -->
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" ref="elform" :rules="rules"> <FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
<template #jbxx> <!-- <template #jbxx>
<div> <div>
<h3 class="tags-title">报送情况</h3> <h3 class="tags-title">报送情况</h3>
<div style="display: flex;justify-content:space-between;width: 200%;"> <div style="width: 200%;">
<div>录入人{{ userName }}</div> <el-descriptions :column="4" border>
<div>录入单位{{ userInfo.deptName }}</div> <el-descriptions-item label="录入人">{{ userName }}</el-descriptions-item>
<div>本年度报送信息量{{ tjcll.cnl || 0 }}</div> <el-descriptions-item label="录入单位">{{ userInfo.deptName }} </el-descriptions-item>
<div>采纳量{{ tjcll.sbsl || 0 }}</div> <el-descriptions-item label="本年度报送信息量:">{{ tjcll.cnl || 0 }}</el-descriptions-item>
<el-descriptions-item label="采纳量">{{ tjcll.sbsl || 0 }} </el-descriptions-item>
</el-descriptions>
</div> </div>
</div> </div>
</template> </template> -->
<template #shzt> <template #shzt>
<div v-if="disabled"> <div v-if="disabled">
<h3 class="tags-title">审核状态</h3> <h3 class="tags-title">审核状态</h3>
@ -564,17 +566,26 @@ defineExpose({ init });
.form-container { .form-container {
display: flex; display: flex;
width: 100%; width: 100%;
height: calc(100% - 50px);
overflow: hidden;
} }
.form-content { .form-content {
// display: flex; flex: 1;
width: 80%; height: 100%;
overflow: hidden;
overflow-y: auto;
} }
.timeline-container { .timeline-container {
width: 400px;
padding-right: 10px;
box-sizing: border-box;
border: 1px solid #ebeef5; border: 1px solid #ebeef5;
flex: 1;
margin: 0 10px; margin: 0 10px;
height: 100%;
overflow: hidden;
overflow-y: auto;
} }
/* 时间线宽度 */ /* 时间线宽度 */

View File

@ -0,0 +1,232 @@
<template>
<div class="inforReport">
<el-dialog :close-on-click-modal="false" :show-close="false" title="信息上报" v-model="visible" width="50%" top="5vh">
<div class="cntBox">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
style="height: 67vh; overflow-y: hidden;"
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
@onChange="handChange"
/>
</div>
<div class="tc mt10">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="downloadWithStyles">下载</el-button>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { connectSSEWithPost } from '@/utils/sse.js'
import { timeValidate } from '@/utils/tools'
import { getItem } from "@/utils/storage";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ref, shallowRef, computed, onBeforeUnmount, onMounted, watch } from "vue";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
data: {
type: Array,
default: () => []
}
})
const baseInfo = {
ssbm:getItem('deptId') ? getItem("deptId")[0].deptName : '',
time:timeValidate(null,'ymd')
}
const emit = defineEmits(['update:modelValue'])
const visible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()
const valueHtml = ref('')// 内容 HTML
const mode = 'default'
const toolbarConfig = {}
const editorConfig = { placeholder: '请输入内容...' }
// 带样式的下载方法
const downloadWithStyles = () => {
const wordDocument = `
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>富文本导出</title>
<style>
/* 应用两端对齐样式 */
body {
text-align: justify;
text-justify: inter-character; /* 中文文本两端对齐 */
font-family: "Microsoft YaHei", Arial, sans-serif;
}
p {
text-align: justify;
text-justify: inter-character;
}
.w-e-text-container [data-slate-editor] .table-container{
border: none !important;
border-bottom: 1px solid #ccc !important;
padding: 10px 10px 0px !important;
border-radius: 0 !important;
}
.w-e-text-container [data-slate-editor] table td, .w-e-text-container [data-slate-editor] table th{
border: none !important;
}
</style>
</head>
<body>
${valueHtml.value}
</body>
</html>
`;
const blob = new Blob([wordDocument], {
type: 'application/msword'
});
saveAs(blob, '情报信息报告.doc');
};
// 处理事件
const handleEvents = async () =>{
// 模拟
// setTimeout(async ()=>{
// let prompt = '对事件的性质、事件的发展,指向性、危害性、可控性等进行分析。'
// if (valueHtml.value.includes('事件分析中。。。')) {
// valueHtml.value = valueHtml.value.replace('事件分析中。。。', prompt)
// }
// },1500)
try {
let prompt = '对事件的性质、事件的发展,指向性、危害性、可控性等进行分析。'
await connectSSEWithPost(prompt, {
onChunk: (content) => {
valueHtml.value = valueHtml.value.replace('事件分析中。。。', content)
},
onComplete: () => {
console.log('SSE连接完成');
},
onError: (error) => {
console.error('SSE连接错误:', error);
}
});
} catch (err) {
valueHtml.value = valueHtml.value.replace('事件分析中。。。', '分析失败,请稍后重试')
console.error('分析失败:', err);
}
}
// 工作指引
const handleWork = async () =>{
// 模拟
// setTimeout(async ()=>{
// let prompt = '根据分析内容,针对性提出一些对策建议。'
// if (valueHtml.value.includes('工作指引分析中。。。')) {
// valueHtml.value = valueHtml.value.replace('工作指引分析中。。。', prompt)
// }
// },1500)
try {
let prompt = '根据分析内容,针对性提出一些对策建议。'
await connectSSEWithPost(prompt, {
onChunk: (content) => {
valueHtml.value = valueHtml.value.replace('工作指引分析中。。。', content)
},
onComplete: () => {
console.log('SSE连接完成');
},
onError: (error) => {
console.error('SSE连接错误:', error);
}
});
} catch (err) {
valueHtml.value = valueHtml.value.replace('工作指引分析中。。。', '分析失败,请稍后重试')
console.error('分析失败:', err);
}
}
const handleHtml = async (val) =>{
let html = `<h1 style="text-align: center; font-size: 32px; font-weight: bold; font-family: 'Songti SC', 'SimSun', serif; margin-bottom: 20px;">
<span style="color: rgb(225, 60, 57);">林芝公安情报信息</span>
</h1>
<table style="width: 100%; border-bottom: 1px solid black; margin-bottom: 30px; font-family: 'FangSong', serif; font-size: 16px; border-collapse: collapse;">
<tr >
<td style="text-align: left; padding-bottom: 10px; border: none;">单位:${baseInfo.ssbm}</td>
<td style="text-align: right; padding-bottom: 10px; border: none;">时间:${baseInfo.time}</td>
</tr>
</table><h2 style="text-align: center;"></h2>
<h2 style="text-align: center; font-size: 24px; font-family: 'SimHei', sans-serif; margin-bottom: 20px;">关于对 XXXX 事件的综合研判</h2>
<p style="text-indent: 2em; line-height: 2; font-family: 'FangSong', serif; font-size: 18px;">近日,${baseInfo.ssbm}(单位)接报 ${val.length} 起关于 XXXXXX 事件的情报信息,合并研判如下:</p>
<h3 style="font-size: 20px; font-weight: bold; margin-top: 20px; margin-bottom: 10px; font-family: 'SimHei', sans-serif;">一、事件概况</h3>`
val.forEach((item,index)=>{
html+=`<p style="text-indent: 2em; line-height: 2; font-family: 'FangSong', serif; font-size: 18px;">事件 ${index+1}${item.qbmc}${item.xsBh}</p>`
})
html+=`<h3 style="font-size: 20px; font-weight: bold; margin-top: 20px; margin-bottom: 10px; font-family: 'SimHei', sans-serif;">二、事件分析</h3>`
html+=`<p style="text-indent: 2em; line-height: 2; font-family: 'FangSong', serif; font-size: 18px;">事件分析中。。。</p>`
html+=`<h3 style="font-size: 20px; font-weight: bold; margin-top: 20px; margin-bottom: 10px; font-family: 'SimHei', sans-serif;">三、工作指引</h3>
<p style="text-indent: 2em; line-height: 2; font-family: 'FangSong', serif; font-size: 18px;">工作指引分析中。。。</p>
`
valueHtml.value = html
await handleWork(html) //工作指引
await handleEvents(html) //处理事件
}
watch(()=>props.data,val=>{
handleHtml(val)
},{immediate:true,deep:true})
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
//内容发生变化
const handChange = (editor) => {
// 判断是否是一个空段落,是空就传空文本
console.log(editor.getHtml(), 'editor.getHtml()');
};
</script>
<style lang="scss" scoped>
.cntBox {
width: 100%;
border: 1px solid #ccc;
margin: 0 auto;
}
</style>
<style lang="scss">
.inforReport{
.w-e-text-container [data-slate-editor] .table-container{
border: none !important;
border-bottom: 1px solid #ccc !important;
padding: 10px 10px 0px !important;
border-radius: 0 !important;
}
.w-e-text-container [data-slate-editor] table td, .w-e-text-container [data-slate-editor] table th{
border: none !important;
}
}
</style>

View File

@ -1,641 +1,40 @@
<template> <template>
<div> <div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Searchs :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" />
</div>
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5"> <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left> <template #left>
<el-button type="primary" @click="addEdit('add')" size="small"> <el-button size="small" v-for="el in tabBtn" :type="tabActive==el?'primary':''" @click="tabActive=el" :key="el">{{ el }}</el-button>
<el-icon class="vertical-middle"> </template>
<CirclePlus />
</el-icon>
<span class="vertical-middle">新增</span>
</el-button>
<el-button type="primary" @click="dologCancel()" size="small">
<el-icon class="vertical-middle">
<CirclePlus />
</el-icon>
<span class="vertical-middle">导出</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="qxkz.deptLevel != '01'"
size="small">
<el-icon class="vertical-middle">
<CirclePlus />
</el-icon>
<span class="vertical-middle">上报</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="delDictItem(ids)" size="small">
<el-icon class="vertical-middle">
<CirclePlus />
</el-icon>
<span class="vertical-middle">删除</span>
</el-button></template>
</PageTitle> </PageTitle>
<!-- 表格 --> <Infomation v-if="tabActive=='信息采集'" />
<div class="tabBox" :style="{ height: (pageData.tableHeight + 40) + 'px' }"> <FQXX v-else-if="tabActive=='蜂群信息'" />
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@chooseData="chooseData" @handleCellClick="openXxqk">
<template #qblx="{ row }">
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
</template>
<template #qbly="{ row }">
<DictTag :tag="false" :value="row.qbly" :options="D_BZ_CJLX" />
</template>
<template #czzt="{ row }">
<DictTag :tag="false" :value="row.czzt" :options="D_BZ_QBCZZT" />
</template>
<template #lczt="{ row }">
<DictTag :tag="false" :value="row.lczt" :options="D_BZ_LCZT" />
</template>
<template #cyqk="{ row }">
<el-link v-if="isShowBtn('采纳')" size="small" type="danger" @click="cnMsg(row)"
:disabled="butcontroll('04', row.lczt)">采纳</el-link>
<!-- 只有上报状态才能回退 -->
<el-link v-if="isShowBtn('回退')" size="small" type="danger" @click="rollbackNewspapers(row)"
:disabled="butcontroll('04', row.lczt)">回退</el-link>
</template>
<!-- 操作 -->
<!-- "市情指挥人员": ["采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门", "送审"], -->
<!-- "县情指人员": ["上报", "回退", "修改", "详情", "送审"], -->
<template #controls="{ row }">
<el-link v-if="isShowBtn('送审', row) && qxkz.deptLevel == '01'" :disabled="row.sldshzt != '00'||row.lczt != '04'" size="small"
type="primary" @click="postXxcjXxcjTjsh(row)">送审</el-link>
<el-link v-if="isShowBtn('送审', row) && qxkz.deptLevel == '02'" :disabled="row.xldshzt != '00'||row.lczt != '04'" size="small"
type="primary" @click="postXxcjXxcjTjsh(row)">送审</el-link>
<!-- 01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 07 转合成 08 转线索 09 转会商v-if="qxkz.deptLevel == '01'" -->
<!-- 在提交和退回得状态才能进行上报 -->
<el-link v-if="isShowBtn('上报')" size="small" type="primary" @click="appearNewspapers(row)" :disabled="row.xldshzt != '02'">上报</el-link>
<el-link v-if="isShowBtn('分组')" size="small" type="primary" @click="opneMsg(row)"
:disabled="row.sldshzt != '02'">分组</el-link>
<!-- 只有领导有肯定 -->
<!-- <el-link v-if="isShowBtn('肯定')" size="small" type="primary" @click="affirm(row)">肯定</el-link> -->
<el-link v-if="isShowBtn('删除')" size="small" type="primary" @clic.stopk="delDictItem(row.id)">删除</el-link>
<el-link v-if="isShowBtn('修改', row)" size="small" type="primary" @click="addEdit('edit', row)">修改</el-link>
<el-link v-if="isShowBtn('续报', row)" size="small" type="primary" @click="addEdit('followUpReport', row)">续报</el-link>
<el-link v-if="isShowBtn('详情')" size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
<!-- 所有状态都能进行转线索 -->
<el-link v-if="isShowBtn('转线索')" size="small" type="primary" @click="FollowUpOnLeads(row)"
:disabled="row.sldshzt != '02' ">转线索</el-link>
<!-- 所有状态都能进行转合成 -->
<!-- <el-link v-if="isShowBtn('转合成')" size="small" type="primary" @click="openFkDialogszl(row)"
:disabled="butcontroll('01', row.lczt)">转合成</el-link> -->
<!-- 所有状态都能进行转会商 -->
<!-- <el-link v-if="isShowBtn('转会商')" size="small" type="primary" @click="handleTransferMerchant(row)"
:disabled="butcontroll('01', row.lczt)">转会商</el-link> -->
<el-link v-if="isShowBtn('关注部门')" :disabled="row.sldshzt != '02'" size="small" type="primary" @click="FollowUpOnDept(row)">关注</el-link>
<!-- 市局能给所有数据创建标签 -->
<el-link v-if="isShowBtn('打标签')" size="small" type="primary" @click="openCustomTag(row)"
:disabled="row.sldshzt != '02' ">打标签</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div> </div>
<!-- 新增 -->
<AddForm ref="detailDiloag" @getList="getList" :titleData="titleData" :dict="{ D_BZ_LCZT, D_BZ_SSSHZT }" />
</div>
<ExportFile v-model="exportFileModel" :tableColumn="tableColumn" :dict="{ D_GS_XS_LY, D_GS_XS_LX, D_GS_XS_LX }"
:dataModel="pageData.tableData" />
<MakeTag v-model="chooseRow" :dataList="dataList" :dict="{ D_BZ_CJLX, D_BZ_QBCZZT, D_GS_XS_LX, D_BZ_BQJB }"
@getList="getList" />
<Fszl v-model="fszlShow" path="/xxcj/sendFqzl" :itemData="dataList" />
<CustomTag v-model="customTagShow" :dataList="dataList" @getList="getList" :dict="{ D_XXCJ_BQLX }" />
<Configuration v-model="configurationShow" :dataList="dataList" @getList="getList" />
<!-- 转会商 -->
<transferMerchant v-if="isShowTransferMerchantTc" :row="currRow" ref="transferMerchantRef" title="转会商"
@close="isShowTransferMerchantTc = false" @ok="getList" />
</template> </template>
<script setup> <script setup>
import PageTitle from "@/components/aboutTable/PageTitle.vue"; import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue"; import Infomation from "./infomation.vue";
import Pages from "@/components/aboutTable/Pages.vue"; import FQXX from "@/views/backOfficeSystem/InformationReporting/index.vue";
import Searchs from "@/components/aboutTable/Search.vue";
import AddForm from "./components/addForm.vue";
import { useRouter, useRoute } from 'vue-router'
import { qbcjSelectQbsbPage, qbcjDeletes, qbcjCzzt, qbcjPlsb } from "@/api/Intelligence.js";
import { xxcjSelectXxsbPage, xxcjDeletes, xxcjXxzsx, xxcjUpdateCzlc, xxcjXxqd, xxcjXxcjTjsh } from '@/api/xxcj.js'
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import MakeTag from '../components/maketag.vue'
import ExportFile from './components/exportFile.vue'
import { ElMessageBox } from 'element-plus'
import { getItem } from '@//utils/storage.js'
import Fszl from '@/views/backOfficeSystem/HumanIntelligence/components/fszl.vue'
import CustomTag from '../components/customTag.vue'
import Configuration from '../components/configuration.vue'
import transferMerchant from "./components/transferMerchant.vue";
import { isShiQingZhi } from "@/utils/auth.js"
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { D_GS_XS_LY, D_BZ_SSSHZT, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, D_BZ_BQJB, const tabBtn=ref(["信息采集","蜂群信息"])
D_GS_XS_QTLX, D_GS_ZDQT_LB, const tabActive=ref('信息采集')
D_BZ_BMJB, D_BZ_CLPP, D_BZ_CLYS, D_BZ_CLLX, D_BZ_XZQHDM, D_BZ_QBCZZT, D_BZ_CJLX, D_BZ_LCZT,
D_XXCJ_BQLX } =
proxy.$dict("D_BZ_BMJB", "D_GS_XS_LY", 'D_BZ_SSSHZT',
"D_BZ_SSZT", "D_BZ_SF", "D_GS_XS_LX", "D_GS_XS_QTLX",
"D_GS_ZDQT_LB", "D_BZ_CLPP", "D_BZ_CLYS", "D_BZ_CLLX", "D_BZ_XZQHDM", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB", "D_BZ_LCZT", "D_XXCJ_BQLX"); //获取字典数据
const detailDiloag = ref();
const searchBox = ref(); //搜索框
const ids = ref([])
const tableList = ref([]);
const chooseData = (val) => {
ids.value = val.map(item => {
return item.id
})
tableList.value = val
}
/** 市情指 */
const cityIntelligenceCommand = isShiQingZhi()
const currRow = ref({})
const transferMerchantRef = ref()
const isShowTransferMerchantTc = ref(false)
const isShow = ref(false)
const searchConfiger = ref([
{ label: "录入人", prop: 'xssbr', placeholder: "请输入录入人", showType: "input" },
{ label: "录入单位", prop: "ssbmdm", placeholder: "请选择录入单位", showType: "department" },
{ label: "编号", prop: 'xsBh', placeholder: "请输入编号", showType: "input" },
{ label: "时间", prop: "startTime", placeholder: "请选择时间", showType: "daterange" },
{ label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" },
{ label: "标签级别", prop: 'qbjb', placeholder: "请选择标签级别", showType: "select", options: D_BZ_BQJB },
{ label: "情报处置状态", prop: 'lczt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_LCZT },
{ label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" },
]);
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "checkBox",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
},
controlsWidth: 300,
tableColumn: [
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报来源", prop: "qbly", showSolt: true },
{ label: "上报人", prop: "xssbr" },
{ label: "上报单位", prop: "ssbm" },
{ label: "流程状态", prop: "lczt", showSolt: true },
{ label: "采用情况", prop: "cyqk", showSolt: true },
// { label: "标签内容", prop: "lczt", showSolt: true },
// { label: "消息状态", prop: "czzt", showSolt: true },
]
});
const queryFrom = ref({});
const chooseRow = ref(false)
const dataList = ref()
// 采纳
const cnMsg = (item) => {
// if ( qxkz.depBool) {
proxy.$confirm("确定要采纳", "警告", { type: "warning" }).then(() => {
xxcjUpdateCzlc({ id: item.id, lczt: '04' }).then(res => {
proxy.$message({ type: "success", message: "采纳成功" });
getList();
})
}).catch(() => { });
// }
}
// 回退
const rollbackNewspapers = (item) => {
// if (item.lczt == '04') {
// proxy.$message({
// message: '已经采纳的信息无法回退',
// type: 'warning',
// showClose: true,
// })
// return
// }
// if (item.lczt == '03') {
// proxy.$message({
// message: '无法回退市局上报信息',
// type: 'warning',
// showClose: true,
// })
// return
// }
if (item.qbjb == '00') {
ElMessageBox.prompt('请输入回退原因', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
})
.then(({ value }) => {
xxcjUpdateCzlc({ id: item.id, lczt: '05', czthyy: value }).then(res => {
proxy.$message({ type: "success", message: "回退成功" });
getList();
})
})
.catch(() => {
})
} else {
proxy.$message({
message: '只能回退已上报的情报',
type: 'warning',
showClose: true,
})
}
}
// 上报
const appearNewspapers = (item) => {
if ((item.lczt == '01' || item.lczt == '05' || item.lczt == '02') && item.qbjb == '00' && qxkz.deptLevel != '01') {
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
let promes = {}
if (qxkz.deptLevel == '02') {
promes = { id: item.id, lczt: '03' }
} else {
promes = { id: item.id, lczt: '02' }
}
xxcjUpdateCzlc(promes).then(res => {
proxy.$message({ type: "success", message: "上报成功" });
getList();
})
}).catch(() => { });
} else {
proxy.$message({ type: "warning", message: "市局无法进行上报" });
}
}
// 分组
const opneMsg = (item) => {
chooseRow.value = true
dataList.value = [item]
}
// 打标签
const customTagShow = ref(false)
const openCustomTag = (item) => {
if (qxkz.depBool) {
customTagShow.value = true
dataList.value = item
} else {
proxy.$message.warning('暂无权限')
}
}
// 肯定
const affirm = (item) => {
proxy.$confirm("确定要肯定吗?", "警告", { type: "warning" }).then(() => {
xxcjXxqd({ ids: item.id }).then(res => {
proxy.$message({ type: "success", message: "肯定成功" });
getList();
})
})
}
// 配置关注部门
const configurationShow = ref(false)
const FollowUpOnDept = (item) => {
if (qxkz.depBool) {
configurationShow.value = true
dataList.value = item
} else {
proxy.$message.warning('暂无权限')
}
}
// 批量分组
// const batchMark = () => {
// const listDb = tableList.value.filter(item => item.lczt != '04')
// if (listDb.length == 0) {
// chooseRow.value = true
// dataList.value = tableList.value
// } else {
// proxy.$message({
// message: '还有情报未采纳',
// type: 'warning',
// showClose: true,
// })
// }
// }
const handleSumbit = () => {
const listDb = tableList.value.filter(item => item.czzt != '01' && item.czzt != '04')
if (listDb.length == 0) {
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
qbcjPlsb({ ids: ids.value, qbjb: '00' }).then(res => {
proxy.$message({ type: "success", message: "上报成功" });
getList();
})
}).catch(() => { });
} else {
proxy.$message({
message: '请选择正确数据',
type: 'warning',
showClose: true,
})
}
}
// <!-- [04、06、07、08、09] -->打标签
// <!-- [03、05] -->采纳
// <!-- [04] -->回退
// <!-- 01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 07 转合成 08 转线索 09 转会商v-if="qxkz.deptLevel == '01'" -->
const butcontroll = (val, zt) => {
switch (val) {
case '01':
return !(['04', '06', '07', '08', '09'].includes(zt))
case '02':
return !(['03', '05'].includes(zt))
case '03':
return !(['02', '03', '04'].includes(zt))
case '04':
return ([ '04', '05' ,'06', '07', '08', '09'].includes(zt))
}
}
// 搜索
const onSearch = (val) => {
const promes = {
...pageData.pageConfiger,
...val,
startTime: val.startTime ? val.startTime[0] : '',
endTime: val.endTime ? val.endTime[1] : '',
}
queryFrom.value = { ...promes }
pageData.pageConfiger.pageCurrent = 1;
getList()
}
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList()
}
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList()
}
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
console.log(pageData.pageConfiger);
let data = { ...pageData.pageConfiger, ...queryFrom.value };
xxcjSelectXxsbPage(data).then(res => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
}).catch(() => { pageData.tableConfiger.loading = false; })
}
// 删除
const delDictItem = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
xxcjDeletes({ ids: Array.isArray(id) ? id : [id] }).then((res) => {
proxy.$message({ type: "success", message: "删除成功" });
getList();
}).catch(() => {
})
}).catch(() => { });
}
// 导出数据
const tableColumn = reactive([
{ label: "上报人姓名", prop: "xssbr" },
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
// { label: "情报类型", prop: "qblx", showSolt: true, zd: 'D_GS_XS_LX' },
{ label: "情报来源", prop: "qbly", showSolt: true, zd: 'D_BZ_CJLX' },
// { label: "指向地点", prop: "zxdz" },
// { label: "情报内容", prop: "qbnr", showOverflowTooltip: true },
])
// 详情
const addEdit = (type, row) => {
isShow.value = true;
setTimeout(() => {
detailDiloag.value.init(type, row);
}, 500)
};
const openXxqk = (row) => {
if (row.column.property == 'qbmc' || row.column.property == 'xsBh') {
isShow.value = true;
setTimeout(() => {
detailDiloag.value.init('info', row.row);
}, 500)
}
}
const route = useRoute()
const titleData = ref()
const qxkz = reactive({
deptBizType: '',
deptLevel: '',
roleCode: false,
depBool: false
});
const qxzt = ref(false)
onMounted(() => { onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.roleCode = getItem('roleList').find(item => item.roleCode == 'JS_666666') != undefined
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
if (deptBizType == '23' && Jb == '01') {
qxkz.depBool = true
} else {
qxkz.depBool = false
}
getRouter()
tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', {
id: route.query.id
});
return
}
getList()
}); });
const getRouter = () => {
titleData.value = route.meta.title
}
const exportFileModel = ref(false)
const dologCancel = () => {
exportFileModel.value = true;
}
// 搜索栏
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
// 转线索
const FollowUpOnLeads = (row) => {
if (!qxkz.depBool) {
proxy.$message({
message: '权限不足',
type: 'warning',
showClose: true,
})
return
} else {
proxy.$confirm("确定要转线索吗?", "警告", { type: "warning" }).then(() => {
xxcjXxzsx({ ids: Array.isArray(row) ? row.join(',') : row.id }).then(res => {
proxy.$message({ type: "success", message: "转线索成功" });
getList();
})
})
}
}
// 发送指令
const fszlShow = ref(false)
const openFkDialogszl = (row) => {
if (!qxkz.depBool) {
proxy.$message({
message: '权限不足',
type: 'warning',
showClose: true,
})
return
} else {
fszlShow.value = true
dataList.value = row
}
}
/** 获取当前角色 */
function getRole() {
const { deptBizType, deptLevel } = getItem('deptId')[0]
/** 是否是市情指领导 */
const isShiQzLeader = getItem('roleList').find(item => item.roleCode == 'JS_666666') != undefined
if (isShiQzLeader) return '市情指领导'
/** 是否是市情指人员 */
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
if (isShiQz) return '市情指挥人员'
/** 是否是县情指人员 */
const isXianQz = getItem('roleList').find(item => item.roleCode == 'JS_888888') != undefined
if (isXianQz) return '县情指人员'
return '部门'
}
/** 是否展示按钮 */
const isShowBtn = (btnName, row = {}) => {
/** @type {String} 流程状态01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 08 转线索) */
const lczt = row.lczt
/** 按钮权限 */
const buttonPermissions = {
"市情指领导": ["肯定", "采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门"],
"市情指挥人员": ["采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门", "送审"],
"县情指人员": ["上报", "回退", "修改", "详情", "送审"],
"部门": ["上报", "新增", "修改", "续报", "详情"]
};
const role = getRole(); // 角色
const isHadAuth = buttonPermissions[role]?.includes(btnName) // 当前角色所有会显示的按钮
if (!isHadAuth) return false
// 拦截部分逻辑
if (role === '部门') {
if (btnName === '续报') return lczt != '01'
if (btnName === '修改') return lczt == '01'
// if(btnName === '上报') return lczt == '01'
}
return true
}
const handleTransferMerchant = (row) => {
currRow.value = row
isShowTransferMerchantTc.value = true
}
// 送审
const postXxcjXxcjTjsh = (row) => {
proxy.$confirm("确定要送审吗", "提示", { type: "warning" }).then(() => {
xxcjXxcjTjsh({ xxid: row.id }).then(res => {
proxy.$message({ type: "success", message: "送审成功" });
getList();
})
}).catch(() => { })
}
const getDisabled = (val, zt) => {
console.log(val, zt);
// switch (val) {
// case '01':
// return !(['04', '06', '07', '08', '09'].includes(zt))
// case '02':
// return !(['03', '05'].includes(zt))
// case '03':
// return !(['02', '03', '04'].includes(zt))
// case '04':
// return ([ '04', '05' ,'06', '07', '08', '09'].includes(zt))
// }
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.label-pop { .marks {
position: relative; padding: 0 4px;
white-space: nowrap;
&::before { background: #73acf1;
position: absolute; border-radius: 4px;
content: '*'; color: #fff;
top: 0;
left: -7px;
color: red;
}
} }
</style> </style>
<style> <style>
.el-loading-mask { .el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important; background: rgba(0, 0, 0, 0.5) !important;
} }
:v-deep .el-dialog {
width: 90% !important;
}
.zdy-model-dialogs {
/* background-color: rgb(50, 148, 214); */
background: url("~@/assets/images/bg46.png") no-repeat center center;
background-size: 100% 100%;
padding: 8px 10px;
box-sizing: border-box;
pointer-events: auto !important;
height: calc(100% - 50px);
overflow: auto;
}
.vertical-middle {
vertical-align: middle;
}
</style> </style>

View File

@ -0,0 +1,615 @@
<template>
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Searchs :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" />
</div>
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left>
<el-button type="primary" @click="addEdit('add')" size="small">
<el-icon class="vertical-middle">
<CirclePlus />
</el-icon>
<span class="vertical-middle">新增</span>
</el-button>
<el-button type="primary" @click="exportFileModel = true;" size="small">
<el-icon class="vertical-middle">
<CirclePlus />
</el-icon>
<span class="vertical-middle">导出</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="qxkz.deptLevel != '01'"
size="small">
<el-icon class="vertical-middle">
<CirclePlus />
</el-icon>
<span class="vertical-middle">上报</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="delDictItem(ids)" size="small">
<el-icon class="vertical-middle">
<CirclePlus />
</el-icon>
<span class="vertical-middle">删除</span>
</el-button>
<el-button type="primary" size="small" @click="handleReport">
<el-icon class="vertical-middle"><Edit /></el-icon>
<span class="vertical-middle">情报信息报告</span>
</el-button>
</template>
</PageTitle>
<!-- 表格 -->
<div class="tabBox" :style="{ height: (pageData.tableHeight + 40) + 'px' }">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@chooseData="chooseData" @handleCellClick="openXxqk">
<template #qblx="{ row }">
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
</template>
<template #qbly="{ row }">
<DictTag :tag="false" :value="row.qbly" :options="D_BZ_CJLX" />
</template>
<template #czzt="{ row }">
<DictTag :tag="false" :value="row.czzt" :options="D_BZ_QBCZZT" />
</template>
<template #lczt="{ row }">
<DictTag :tag="false" :value="row.lczt" :options="D_BZ_LCZT" />
</template>
<template #cyqk="{ row }">
<el-link v-if="isShowBtn('采纳')" size="small" type="danger" @click="cnMsg(row)"
:disabled="butcontroll('04', row.lczt)">采纳</el-link>
<!-- 只有上报状态才能回退 -->
<el-link v-if="isShowBtn('回退')" size="small" type="danger" @click="rollbackNewspapers(row)"
:disabled="butcontroll('04', row.lczt)">回退</el-link>
</template>
<!-- 操作 -->
<!-- "市情指挥人员": ["采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门", "送审"], -->
<!-- "县情指人员": ["上报", "回退", "修改", "详情", "送审"], -->
<template #controls="{ row }">
<el-link
v-if="isShowBtn('送审', row) && qxkz.deptLevel == '01'"
:disabled="!(row.lczt == '04')||row.sldshzt != '00'"
size="small" type="primary"
@click="postXxcjXxcjTjsh(row)">
送审
</el-link>
<!-- <el-link
v-if="isShowBtn('送审', row) && qxkz.deptLevel == '02'"
:disabled="row.xldshzt != '00' "
size="small" type="primary"
@click="postXxcjXxcjTjsh(row)">
送审
</el-link> -->
<!-- 01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 07 转合成 08 转线索 09 转会商v-if="qxkz.deptLevel == '01'" -->
<el-link v-if="isShowBtn('上报') && qxkz.deptLevel == '03'" size="small" type="primary" @click="appearNewspapers(row)" :disabled="row.lczt != '01'">上报</el-link>
<el-link v-else-if="isShowBtn('上报')" size="small" type="primary" @click="appearNewspapers(row)" :disabled="!(row.xldshzt == '02'&&row.lczt == '02')">上报</el-link>
<!-- && row.lczt != '02' -->
<el-link v-if="isShowBtn('分组')" size="small" type="primary" @click="opneMsg(row)"
:disabled="row.sldshzt != '02'">分组</el-link>
<!-- 只有领导有肯定 -->
<!-- <el-link v-if="isShowBtn('肯定')" size="small" type="primary" @click="affirm(row)">肯定</el-link> -->
<el-link v-if="isShowBtn('删除')" size="small" type="primary" @clic.stopk="delDictItem(row.id)">删除</el-link>
<el-link v-if="isShowBtn('修改', row)" size="small" type="primary" @click="addEdit('edit', row)">修改</el-link>
<el-link v-if="isShowBtn('续报', row)" size="small" type="primary"
@click="addEdit('followUpReport', row)">续报</el-link>
<el-link v-if="isShowBtn('详情')" size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
<!-- 所有状态都能进行转线索 -->
<el-link v-if="isShowBtn('转线索')" size="small" type="primary" @click="FollowUpOnLeads(row)"
:disabled="row.sldshzt != '02'">转线索</el-link>
<!-- 所有状态都能进行转合成 -->
<!-- <el-link v-if="isShowBtn('转合成')" size="small" type="primary" @click="openFkDialogszl(row)" :disabled="butcontroll('01', row.lczt)">转合成</el-link> -->
<!-- 所有状态都能进行转会商 -->
<!-- <el-link v-if="isShowBtn('转会商')" size="small" type="primary" @click="handleTransferMerchant(row)" :disabled="butcontroll('01', row.lczt)">转会商</el-link> -->
<el-link v-if="isShowBtn('关注部门') && row.qbjb=='01'" :disabled="row.sldshzt != '02'" size="small" type="primary" @click="FollowUpOnDept(row)">关注</el-link>
<!-- 市局能给所有数据创建标签 -->
<el-link v-if="isShowBtn('打标签')" size="small" type="primary" @click="openCustomTag(row)" :disabled="row.sldshzt != '02'">打标签</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div>
<!-- 新增 -->
<AddForm ref="detailDiloag" @getList="getList" :titleData="titleData" :dict="{ D_BZ_LCZT, D_BZ_SSSHZT }" />
</div>
<ExportFile
v-model="exportFileModel"
:tableColumn="tableColumn"
:dict="{ D_GS_XS_LY, D_GS_XS_LX, D_GS_XS_LX }"
:dataModel="pageData.tableData"
/>
<MakeTag
v-model="chooseRow"
:dataList="dataList"
:dict="{ D_BZ_CJLX, D_BZ_QBCZZT, D_GS_XS_LX, D_BZ_BQJB }"
@getList="getList"
/>
<Fszl
v-model="fszlShow"
path="/xxcj/sendFqzl"
:itemData="dataList"
/>
<CustomTag
v-model="customTagShow"
:dataList="dataList"
@getList="getList"
:dict="{ D_XXCJ_BQLX }"
/>
<Configuration
v-model="configurationShow"
:dataList="dataList"
@getList="getList"
/>
<!-- 转会商 -->
<transferMerchant
v-if="isShowTransferMerchantTc"
:row="currRow"
title="转会商"
@close="isShowTransferMerchantTc = false"
@ok="getList"
/>
<!-- 情报信息报告 -->
<InforReport v-if="inforReportShow" v-model="inforReportShow" :data="tableList" />
</template>
<script setup>
import InforReport from './components/inforReport.vue'
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Searchs from "@/components/aboutTable/Search.vue";
import AddForm from "./components/addForm.vue";
import { useRouter, useRoute } from 'vue-router'
import { qbcjSelectQbsbPage, qbcjDeletes, qbcjCzzt, qbcjPlsb } from "@/api/Intelligence.js";
import { xxcjSelectXxsbPage, xxcjDeletes, xxcjXxzsx, xxcjUpdateCzlc, xxcjXxqd, xxcjXxcjTjsh } from '@/api/xxcj.js'
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import MakeTag from '../components/maketag.vue'
import ExportFile from './components/exportFile.vue'
import { ElMessageBox } from 'element-plus'
import { getItem } from '@//utils/storage.js'
import Fszl from '@/views/backOfficeSystem/HumanIntelligence/components/fszl.vue'
import CustomTag from '../components/customTag.vue'
import Configuration from '../components/configuration.vue'
import transferMerchant from "./components/transferMerchant.vue";
import { Edit } from "@element-plus/icons";
const { proxy } = getCurrentInstance();
const { D_GS_XS_LY, D_BZ_SSSHZT, D_GS_XS_LX, D_BZ_BQJB,D_BZ_QBCZZT, D_BZ_CJLX, D_BZ_LCZT,D_XXCJ_BQLX } = proxy.$dict( "D_GS_XS_LY", 'D_BZ_SSSHZT',"D_GS_XS_LX", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB", "D_BZ_LCZT", "D_XXCJ_BQLX"); //获取字典数据
const route = useRoute()
const titleData = ref()
const exportFileModel = ref(false)
const qxkz = reactive({
deptBizType: '',
deptLevel: '',
roleCode: false,
depBool: false
});
const fszlShow = ref(false)// 发送指令
const detailDiloag = ref();
const inforReportShow = ref(false) //情报信息报告
const customTagShow = ref(false)// 打标签
const configurationShow = ref(false)// 配置关注部门
const searchBox = ref(); //搜索框
const ids = ref([])
const tableList = ref([]);
const currRow = ref({})
const isShowTransferMerchantTc = ref(false)
const isShow = ref(false)
const searchConfiger = ref([
{ label: "录入人", prop: 'xssbr', placeholder: "请输入录入人", showType: "input" },
{ label: "录入单位", prop: "ssbmdm", placeholder: "请选择录入单位", showType: "department" },
{ label: "编号", prop: 'xsBh', placeholder: "请输入编号", showType: "input" },
{ label: "时间", prop: "startTime", placeholder: "请选择时间", showType: "daterange" },
{ label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" },
{ label: "标签内容", prop: 'bqdmList', placeholder: "请选择标签内容", showType: "select", options: D_XXCJ_BQLX, multiple: true },
{ label: "标签级别", prop: 'qbjb', placeholder: "请选择标签级别", showType: "select", options: D_BZ_BQJB },
{ label: "情报处置状态", prop: 'lczt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_LCZT },
{ label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" },
]);
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "checkBox",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
},
controlsWidth: 300,
tableColumn: [
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报来源", prop: "qbly", showSolt: true },
{ label: "上报人", prop: "xssbr" },
{ label: "上报单位", prop: "ssbm" },
{ label: "流程状态", prop: "lczt", showSolt: true },
{ label: "采用情况", prop: "cyqk", showSolt: true },
]
});
// 导出数据
const tableColumn = reactive([
{ label: "上报人姓名", prop: "xssbr" },
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报来源", prop: "qbly", showSolt: true, zd: 'D_BZ_CJLX' },
])
const queryFrom = ref({});
const chooseRow = ref(false)
const dataList = ref()
const chooseData = (val) => {
ids.value = val.map(item => item.id)
tableList.value = val
}
// 采纳
const cnMsg = (item) => {
proxy.$confirm("确定要采纳", "警告", { type: "warning" }).then(() => {
xxcjUpdateCzlc({ id: item.id, lczt: '04' }).then(res => {
proxy.$message({ type: "success", message: "采纳成功" });
getList();
})
}).catch(() => { });
}
const handleReport = () => {
if(tableList.value.length == 0) return proxy.$message({ type: "warning", message: "请选择情报信息" });
inforReportShow.value = true
}
// 回退
const rollbackNewspapers = (item) => {
// if (item.lczt == '04') {
// proxy.$message({
// message: '已经采纳的信息无法回退',
// type: 'warning',
// showClose: true,
// })
// return
// }
// if (item.lczt == '03') {
// proxy.$message({
// message: '无法回退市局上报信息',
// type: 'warning',
// showClose: true,
// })
// return
// }
if (item.qbjb == '00') {
ElMessageBox.prompt('请输入回退原因', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
})
.then(({ value }) => {
xxcjUpdateCzlc({ id: item.id, lczt: '05', czthyy: value }).then(res => {
proxy.$message({ type: "success", message: "回退成功" });
getList();
})
})
.catch(() => {
})
} else {
proxy.$message({
message: '只能回退已上报的情报',
type: 'warning',
showClose: true,
})
}
}
// 上报
const appearNewspapers = (item) => {
if ((item.lczt == '01' || item.lczt == '05' || item.lczt == '02') && item.qbjb == '00' && qxkz.deptLevel != '01') {
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
let promes = { id: item.id }
promes.lczt = qxkz.deptLevel == '02' ? '03' : '02';
xxcjUpdateCzlc(promes).then(res => {
proxy.$message({ type: "success", message: "上报成功" });
getList();
})
}).catch(() => { });
} else {
proxy.$message({ type: "warning", message: "市局无法进行上报" });
}
}
// 分组
const opneMsg = (item) => {
chooseRow.value = true
dataList.value = [item]
}
const openCustomTag = (item) => {
if (qxkz.depBool) {
customTagShow.value = true
dataList.value = item
} else {
proxy.$message.warning('暂无权限')
}
}
// 肯定
const affirm = (item) => {
proxy.$confirm("确定要肯定吗?", "警告", { type: "warning" }).then(() => {
xxcjXxqd({ ids: item.id }).then(res => {
proxy.$message({ type: "success", message: "肯定成功" });
getList();
})
})
}
const FollowUpOnDept = (item) => {
if (qxkz.depBool) {
configurationShow.value = true
dataList.value = item
} else {
proxy.$message.warning('暂无权限')
}
}
// 批量分组
// const batchMark = () => {
// const listDb = tableList.value.filter(item => item.lczt != '04')
// if (listDb.length == 0) {
// chooseRow.value = true
// dataList.value = tableList.value
// } else {
// proxy.$message({
// message: '还有情报未采纳',
// type: 'warning',
// showClose: true,
// })
// }
// }
const handleSumbit = () => {
const listDb = tableList.value.filter(item => item.czzt != '01' && item.czzt != '04')
if (listDb.length == 0) {
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
qbcjPlsb({ ids: ids.value, qbjb: '00' }).then(res => {
proxy.$message({ type: "success", message: "上报成功" });
getList();
})
}).catch(() => { });
} else {
proxy.$message({ message: '请选择正确数据', type: 'warning', showClose: true })
}
}
// <!-- [04、06、07、08、09] -->打标签
// <!-- [03、05] -->采纳
// <!-- [04] -->回退
// <!-- 01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 07 转合成 08 转线索 09 转会商v-if="qxkz.deptLevel == '01'" -->
const butcontroll = (val, zt) => {
switch (val) {
case '01':
return !(['04', '06', '07', '08', '09'].includes(zt))
case '02':
return !(['03', '05'].includes(zt))
case '03':
return !(['02', '03', '04'].includes(zt))
case '04':
return (['04', '05', '06', '07', '08', '09'].includes(zt))
}
}
// 搜索
const onSearch = (val) => {
const promes = {
...pageData.pageConfiger,
...val,
startTime: val.startTime ? val.startTime[0] : '',
endTime: val.endTime ? val.endTime[1] : '',
bqdmList: val.bqdmList ? val.bqdmList.join(',') : ""
}
queryFrom.value = { ...promes }
pageData.pageConfiger.pageCurrent = 1;
getList()
}
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList()
}
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList()
}
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value };
xxcjSelectXxsbPage(data).then(res => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
}).catch(() => { pageData.tableConfiger.loading = false; })
}
// 删除
const delDictItem = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
xxcjDeletes({ ids: Array.isArray(id) ? id : [id] }).then((res) => {
proxy.$message({ type: "success", message: "删除成功" });
getList();
}).catch(() => {
})
}).catch(() => { });
}
// 详情
const addEdit = (type, row) => {
isShow.value = true;
setTimeout(() => {
detailDiloag.value.init(type, row);
}, 500)
};
const openXxqk = (row) => {
if (row.column.property == 'qbmc' || row.column.property == 'xsBh') {
isShow.value = true;
setTimeout(() => {
detailDiloag.value.init('info', row.row);
}, 500)
}
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 280;
window.onresize = function () {
tabHeightFn();
};
};
// 转线索
const FollowUpOnLeads = (row) => {
if (!qxkz.depBool) return proxy.$message({message: '权限不足',type: 'warning',showClose: true, })
proxy.$confirm("确定要转线索吗?", "警告", { type: "warning" }).then(() => {
xxcjXxzsx({ ids: Array.isArray(row) ? row.join(',') : row.id }).then(res => {
proxy.$message({ type: "success", message: "转线索成功" });
getList();
})
})
}
const openFkDialogszl = (row) => {
if (!qxkz.depBool) {
proxy.$message({
message: '权限不足',
type: 'warning',
showClose: true,
})
return
} else {
fszlShow.value = true
dataList.value = row
}
}
/** 获取当前角色 */
function getRole() {
const { deptBizType, deptLevel } = getItem('deptId')[0]
/** 是否是市情指领导 */
const isShiQzLeader = getItem('roleList').find(item => item.roleCode == 'JS_666666') != undefined
if (isShiQzLeader) return '市情指领导'
/** 是否是市情指人员 */
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
if (isShiQz) return '市情指挥人员'
/** 是否是县情指人员 */
const isXianQz = getItem('roleList').find(item => item.roleCode == 'JS_888888') != undefined
if (isXianQz) return '县情指人员'
return '部门'
}
/** 是否展示按钮 */
const isShowBtn = (btnName, row = {}) => {
/** @type {String} 流程状态01 提交 02 上报县局 03 上班市局 04 采纳 05 退回 06 打标签 08 转线索) */
const lczt = row.lczt
/** 按钮权限 */
const buttonPermissions = {
"市情指领导": ["肯定", "采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门"],
"市情指挥人员": ["采纳", "回退", "分组", "转线索", "转合成", "转会商", "打标签", "修改", "详情", "关注部门", "送审"],
"县情指人员": ["上报", "回退", "修改", "详情", "送审"],
"部门": ["上报", "新增", "修改", "续报", "详情"]
};
const role = getRole(); // 角色
const isHadAuth = buttonPermissions[role]?.includes(btnName) // 当前角色所有会显示的按钮
if (!isHadAuth) return false
// 拦截部分逻辑
if (role === '部门') {
if (btnName === '续报') return lczt != '01'
if (btnName === '修改') return lczt == '01'
}
return true
}
const handleTransferMerchant = (row) => {
currRow.value = row
isShowTransferMerchantTc.value = true
}
// 送审
const postXxcjXxcjTjsh = (row) => {
proxy.$confirm("确定要送审吗", "提示", { type: "warning" }).then(() => {
xxcjXxcjTjsh({ xxid: row.id }).then(res => {
proxy.$message({ type: "success", message: "送审成功" });
getList();
})
}).catch(() => { })
}
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.roleCode = getItem('roleList').find(item => item.roleCode == 'JS_666666') != undefined
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
if (deptBizType == '23' && Jb == '01') {
qxkz.depBool = true
} else {
qxkz.depBool = false
}
console.log(qxkz,'=======qxkz');
titleData.value = route.meta.title
tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', { id: route.query.id });
}
getList()
});
</script>
<style lang="scss" scoped>
.label-pop {
position: relative;
&::before {
position: absolute;
content: '*';
top: 0;
left: -7px;
color: red;
}
}
</style>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
:v-deep .el-dialog {
width: 90% !important;
}
.zdy-model-dialogs {
/* background-color: rgb(50, 148, 214); */
background: url("~@/assets/images/bg46.png") no-repeat center center;
background-size: 100% 100%;
padding: 8px 10px;
box-sizing: border-box;
pointer-events: auto !important;
height: calc(100% - 50px);
overflow: auto;
}
.vertical-middle {
vertical-align: middle;
}
</style>

View File

@ -1,6 +1,5 @@
<template> <template>
<div> <div>
<!-- 搜索 --> <!-- 搜索 -->
<div ref="searchBox" class="mt10"> <div ref="searchBox" class="mt10">
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" /> <Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" />
@ -14,7 +13,6 @@
<span style="vertical-align: middle">导出</span> <span style="vertical-align: middle">导出</span>
</el-button> </el-button>
</template> </template>
<!-- <el-button v-if="qxkz.deptLevel == '01'" type="primary" :disabled="ids.length === 0" @click="batchMark(ids)"> <!-- <el-button v-if="qxkz.deptLevel == '01'" type="primary" :disabled="ids.length === 0" @click="batchMark(ids)">
<el-icon style="vertical-align: middle"> <el-icon style="vertical-align: middle">
<CirclePlus /> <CirclePlus />
@ -24,9 +22,15 @@
</PageTitle> </PageTitle>
<!-- 表格 --> <!-- 表格 -->
<div class="tabBox"> <div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight" <MyTable
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth" :tableData="pageData.tableData"
@chooseData="chooseData"> :tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
@chooseData="chooseData"
>
<template #qblx="{ row }"> <template #qblx="{ row }">
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" /> <DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
</template> </template>
@ -46,6 +50,9 @@
<el-link size="small" type="primary" @click="openCheckProcess(row)">补充信息</el-link> <el-link size="small" type="primary" @click="openCheckProcess(row)">补充信息</el-link>
<!-- <el-link size="small" type="primary" @click="openCheckProcessXb(row)"> 续报</el-link> --> <!-- <el-link size="small" type="primary" @click="openCheckProcessXb(row)"> 续报</el-link> -->
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link> <el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
<el-link size="small" type="primary" @click="handleCase(row)">
<span :style="{'color': row.sfgz == '0' ? 'rgb(242,7,7)' : '#dede17'}">{{ row.sfgz == '0' ? '关注' : '取消关注' }}</span>
</el-link>
</template> </template>
</MyTable> </MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{ <Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
@ -79,60 +86,58 @@
</template> </template>
<script setup> <script setup>
import { qcckPost } from "@/api/qcckApi.js";
import PageTitle from "@/components/aboutTable/PageTitle.vue"; import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue"; import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue"; import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue"; import Search from "@/components/aboutTable/Search.vue";
import AddForm from "@/views/backOfficeSystem/HumanIntelligence/infoCollection/components/addForm.vue"; import AddForm from "@/views/backOfficeSystem/HumanIntelligence/infoCollection/components/addForm.vue";
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { qbcjSelectPage, qbcjDeletes } from "@/api/Intelligence.js";
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
import MakeTag from '@/views/backOfficeSystem/HumanIntelligence/components/maketag.vue' import MakeTag from '@/views/backOfficeSystem/HumanIntelligence/components/maketag.vue'
import ExportFile from '@/views/backOfficeSystem/HumanIntelligence/infoCollection/components/exportFile.vue' import ExportFile from '@/views/backOfficeSystem/HumanIntelligence/infoCollection/components/exportFile.vue'
import pursueContent from "../components/pursueContent.vue"; import pursueContent from "../components/pursueContent.vue";
import Fszl from '../components/fszl.vue' import Fszl from '../components/fszl.vue'
import { getItem } from '@//utils/storage.js' import { getItem } from '@//utils/storage.js'
import { qbcjZxs } from '@/api/qbcj.js'
import {xxcjSelectPage,xxcjXxzsx} from '@/api/xxcj.js' import {xxcjSelectPage,xxcjXxzsx} from '@/api/xxcj.js'
import { color } from "echarts";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, D_BZ_BQJB, const {
D_GS_XS_QTLX, D_GS_ZDQT_LB, D_GS_XS_LY,
D_BZ_BMJB, D_BZ_CLPP, D_BZ_CLYS, D_BZ_CLLX, D_BZ_XZQHDM, D_BZ_QBCZZT, D_BZ_CJLX ,D_BZ_LCZT} = D_BZ_SSZT,
proxy.$dict("D_BZ_BMJB", "D_GS_XS_LY", D_BZ_SF,
"D_BZ_SSZT", "D_BZ_SF", "D_GS_XS_LX", "D_GS_XS_QTLX", D_GS_XS_LX,
"D_GS_ZDQT_LB", "D_BZ_CLPP", "D_BZ_CLYS", "D_BZ_CLLX", "D_BZ_XZQHDM", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB","D_BZ_LCZT"); //获取字典数据 D_BZ_BQJB,
D_GS_XS_QTLX,
D_GS_ZDQT_LB,
D_BZ_BMJB,
D_BZ_CLPP,
D_BZ_CLYS,
D_BZ_CLLX,
D_BZ_XZQHDM,
D_BZ_QBCZZT,
D_BZ_CJLX ,D_BZ_LCZT } =
proxy.$dict(
"D_BZ_BMJB",
"D_GS_XS_LY",
"D_BZ_SSZT",
"D_BZ_SF",
"D_GS_XS_LX",
"D_GS_XS_QTLX",
"D_GS_ZDQT_LB",
"D_BZ_CLPP",
"D_BZ_CLYS",
"D_BZ_CLLX",
"D_BZ_XZQHDM",
"D_BZ_QBCZZT",
"D_BZ_CJLX",
"D_BZ_BQJB",
"D_BZ_LCZT"
); //获取字典数据
const detailDiloag = ref(); const detailDiloag = ref();
const searchBox = ref(); //搜索框 const searchBox = ref(); //搜索框
const ids = ref([]) const ids = ref([])
const tableList = ref([]); const tableList = ref([]);
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
qxkz.userName = getItem('USERNAME')
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
if (deptBizType == '23' && Jb == '01') {
qxkz.depBool = true
} else {
qxkz.depBool = false
}
getRouter()
tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', {
id: route.query.id
});
return
}
getList()
});
const chooseData = (val) => {
ids.value = val.map(item => {
return item.id
})
tableList.value = val
}
const qxkz = reactive({ const qxkz = reactive({
deptBizType: "", deptBizType: "",
deptLevel: "", deptLevel: "",
@ -140,20 +145,37 @@ const qxkz = reactive({
}) })
const list = ref() const list = ref()
const searchConfiger = ref(); const searchConfiger = ref();
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
qxkz.userName = getItem('USERNAME')
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
qxkz.depBool = deptBizType == '23' && Jb == '01' ? true : false;
getRouter()
tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', { id: route.query.id });
return
}
getList()
});
const chooseData = (val) => {
ids.value = val.map(item => item.id)
tableList.value = val
}
watch(() => D_BZ_BQJB, val => { watch(() => D_BZ_BQJB, val => {
if (qxkz.deptLevel == '01') { if (qxkz.deptLevel == '01') {
list.value = val.value.filter(item => { list.value = val.value.filter(item => item.dm != '00')
return item.dm != '00'
})
} else if (qxkz.deptLevel == '02') { } else if (qxkz.deptLevel == '02') {
list.value = val.value.filter(item => { list.value = val.value.filter(item => (item.dm == '01' || item.dm == '02'))
return item.dm == '01' || item.dm == '02'
})
} else { } else {
list.value = [] list.value = []
} }
searchConfiger.value = [ searchConfiger.value = [
{ label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" }, { label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" },
{ label: "情报处置状态", prop: 'lczt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_LCZT }, { label: "情报处置状态", prop: 'lczt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_LCZT },
// { label: "线索编号", prop: 'xsBh', placeholder: "请输入线索编号", showType: "input" }, // { label: "线索编号", prop: 'xsBh', placeholder: "请输入线索编号", showType: "input" },
{ label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" }, { label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" },
@ -184,10 +206,8 @@ const pageData = reactive({
] ]
}); });
const queryFrom = ref({}); const queryFrom = ref({});
const chooseRow = ref(false) const chooseRow = ref(false)
const dataList = ref() const dataList = ref()
// 搜索 // 搜索
const onSearch = (val) => { const onSearch = (val) => {
const { lrkssj, zxkssj } = val const { lrkssj, zxkssj } = val
@ -198,9 +218,7 @@ const onSearch = (val) => {
lrjssj: lrkssj ? lrkssj[1] : '', lrjssj: lrkssj ? lrkssj[1] : '',
zxkssj: zxkssj ? zxkssj[0] : '', zxkssj: zxkssj ? zxkssj[0] : '',
zxjssj: zxkssj ? zxkssj[1] : '', zxjssj: zxkssj ? zxkssj[1] : '',
} }
queryFrom.value = { ...promes } queryFrom.value = { ...promes }
pageData.pageConfiger.pageCurrent = 1; pageData.pageConfiger.pageCurrent = 1;
getList() getList()
@ -243,6 +261,16 @@ const addEdit = (type, row) => {
detailDiloag.value.init(type, row); detailDiloag.value.init(type, row);
}, 500) }, 500)
}; };
const handleCase = (row) => {
let text = row.sfgz == '0' ? '关注' : '取消关注';
proxy.$confirm("确定要" + text + "吗?", "警告", { type: "warning" }).then(() => {
qcckPost({ id: row.id,sfgz: row.sfgz == '0' ? '1' : '0' },'/mosty-gsxt/xxcj/cjgz').then(res => {
proxy.$message({ type: "success", message: text + "成功" });
getList();
})
})
}
// 表格高度计算 // 表格高度计算
const tabHeightFn = () => { const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250; pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;

View File

@ -0,0 +1,119 @@
<template>
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<!-- 表格 -->
<div class="tabBox mt10" :style="{height: pageData.tableHeight +30+ 'px'}">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"
/>
</div>
/>
</div>
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import { qcckGet } from "@/api/qcckApi.js";
import { reactive, ref, onMounted } from "vue";
const searchBox = ref(); //搜索框
const searchConfiger = ref([
{ label: "申请人姓名", prop: "xm", placeholder: "请输入申请人姓名", showType: "input" },
{ label: "申请人身份证", prop: "sfzh", placeholder: "请输入申请人身份证号", showType: "input"},
{ label: "申请人联系电话", prop: "lxdh", placeholder: "请输入申请人联系电话", showType: "input"}
]);
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false,
haveControls: false
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
},
controlsWidth: 200,
tableColumn: [
{ label: "申请人姓名", prop: "xm" },
{ label: "申请人身份证", prop: "sfzh"},
{ label: "申请人联系电话", prop: "lxdh" },
{ label: "提交人姓名", prop: "tjrxm"},
{ label: "提交人身份证号", prop: "tjrsfzh"},
{ label: "权限说明", prop: "qxsm", showOverflowTooltip: true },
]
});
const queryFrom = ref({});
onMounted(() => {
getList();
tabHeightFn();
});
// 搜索
const onSearch = (val) => {
queryFrom.value = { ...val };
pageData.pageConfiger.pageCurrent = 1;
getList();
};
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value };
qcckGet(data, "/mosty-gsxt/gsxt/qxsq/getPageList").then((res) => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
}).catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 220;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>

View File

@ -76675,35 +76675,40 @@ export const centralPoint = [
95.7692249914358, 95.7692249914358,
29.85943760031867 29.85943760031867
] ]
}, { },
{
name: '察隅县', name: '察隅县',
ssbmdm: '540425000000', ssbmdm: '540425000000',
point: [ point: [
97.46698612723947, 97.46698612723947,
28.661228694163327 28.661228694163327
] ]
}, { },
{
name: '工布江达县', name: '工布江达县',
ssbmdm: '540421000000', ssbmdm: '540421000000',
point: [ point: [
93.24660931130188, 93.24660931130188,
29.88459424127838 29.88459424127838
] ]
}, { },
{
name: '朗县', name: '朗县',
ssbmdm: '540426000000', ssbmdm: '540426000000',
point: [ point: [
93.07449497318652, 93.07449497318652,
29.045416229209337 29.045416229209337
] ]
}, { },
{
name: '米林县', name: '米林县',
ssbmdm: '540422000000', ssbmdm: '540422000000',
point: [ point: [
94.21305189935441, 94.21305189935441,
29.21583429482142 29.21583429482142
] ]
}, { },
{
name: '雅下分局', name: '雅下分局',
ssbmdm: '540481450000', ssbmdm: '540481450000',
point: [ point: [

View File

@ -70,15 +70,12 @@ const disabled = ref(false);
// 初始化数据 // 初始化数据
const init = (type, row) => { const init = (type, row) => {
title.value = type == 'edit' ? '编辑' : '新增'
dialogForm.value = true; dialogForm.value = true;
if(type == 'edit'){
}
}; };
// 根据id查询详情
const getDataById = (id) => {
// qcckGet({id}, "/mosty-gsxt/tbGsxtZdcl/selectByid").then((res) => {
// listQuery.value = res;
// listQuery.value.fjdz = listQuery.value.fjdz?.split(",");
// });
};
// 提交 // 提交
const submit = () => { const submit = () => {
@ -90,9 +87,6 @@ const submit = () => {
return { bqdl: listQuery.value.dlid, bqdm: item.bqDm, bqmc: item.bqMc, bqsm: item.bqSm, bqys: item.bqYs } return { bqdl: listQuery.value.dlid, bqdm: item.bqDm, bqmc: item.bqMc, bqsm: item.bqSm, bqys: item.bqYs }
}) })
const promes = [...a, ...b] const promes = [...a, ...b]
// data.fjdz = data.fjdz?.join(",");
let url = title.value == "新增" ? "/mosty-gsxt/gsxt/bqbk/saveList" : "/mosty-gsxt/tbGsxtZdcl/update"; let url = title.value == "新增" ? "/mosty-gsxt/gsxt/bqbk/saveList" : "/mosty-gsxt/tbGsxtZdcl/update";
loading.value = true; loading.value = true;

View File

@ -139,8 +139,8 @@ const getList = () => {
pageData.tableConfiger.loading = false; pageData.tableConfiger.loading = false;
}); });
}; };
const AddFrom = () => { const AddFrom = (type,row) => {
addForm.value.init() addForm.value.init(type,row)
} }
const handleItem = (type,row) => { const handleItem = (type,row) => {
proxy.$confirm('确认撤控吗?', '提示', { proxy.$confirm('确认撤控吗?', '提示', {

View File

@ -19,34 +19,34 @@
</tr> </tr>
<tr> <tr>
<td class="hzd-label">布控来源</td> <td class="hzd-label">布控来源</td>
<td class="hzd-value">{{ listQuery.ly }}</td> <td class="hzd-value" contenteditable="true">{{ listQuery.ly }}</td>
<td class="hzd-label">布控范围</td> <td class="hzd-label">布控范围</td>
<td class="hzd-value">全市工布江达县</td> <td class="hzd-value" contenteditable="true">全市工布江达县</td>
</tr> </tr>
<tr> <tr>
<td class="hzd-label">布控级别</td> <td class="hzd-label">布控级别</td>
<td class="hzd-value">{{ listQuery.dj }}</td> <td class="hzd-value" contenteditable="true">{{ listQuery.dj }}</td>
<td class="hzd-label">处置要求</td> <td class="hzd-label">处置要求</td>
<td class="hzd-value">{{ listQuery.czyq }}</td> <td class="hzd-value" contenteditable="true">{{ listQuery.czyq }}</td>
</tr> </tr>
<tr> <tr>
<td class="hzd-label">经办人员</td> <td class="hzd-label">经办人员</td>
<td class="hzd-value">{{ listQuery.bkcjrXm }}</td> <td class="hzd-value" contenteditable="true">{{ listQuery.bkcjrXm }}</td>
<td class="hzd-label">联系方式</td> <td class="hzd-label">联系方式</td>
<td class="hzd-value"> <td class="hzd-value">
<el-input v-model="listQuery.lxfs" style="width: 100%" placeholder="请输入经办人联系方式" /> <div contenteditable="true"> {{ listQuery.lxfs }}</div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="hzd-label">布控理由</td> <td class="hzd-label">布控理由</td>
<td class="hzd-value" colspan="3"> <td class="hzd-value" colspan="3">
<el-input v-model="listQuery.bkSy" style="width: 100%" placeholder="请输入布控理由" /> <div contenteditable="true"> {{ listQuery.bkSy }}</div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="hzd-label">执法依据</td> <td class="hzd-label">执法依据</td>
<td class="hzd-value" colspan="3"> <td class="hzd-value" colspan="3">
<el-input v-model="listQuery.zfyj" style="width: 100%" placeholder="请输入执法依据" /> <div contenteditable="true"> {{ listQuery.zfyj }}</div>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -68,8 +68,7 @@
<tr> <tr>
<td class="hzd-label">备注</td> <td class="hzd-label">备注</td>
<td class="hzd-value" colspan="3"> <td class="hzd-value" colspan="3">
<el-input v-model="listQuery.bz" type="textarea" style="width: 100%" placeholder="请输入备注" /> <div contenteditable="true"> {{ listQuery.bz }}</div>
<div v-show="false" class="input-value">{{ listQuery.bz }}</div>
</td> </td>
</tr> </tr>
</table> </table>
@ -260,4 +259,10 @@ const exportWord = () => {
.hzd-table td[colspan="3"] { .hzd-table td[colspan="3"] {
width: calc(100% - 150px); width: calc(100% - 150px);
} }
</style>
<style>
</style> </style>

View File

@ -55,7 +55,7 @@
</template> </template>
<!-- 审核通过后才有轨迹 --> <!-- 审核通过后才有轨迹 -->
<el-link type="primary" size="small" @click="openShowHzd(row)">回执单</el-link> <el-link type="primary" size="small" @click="openShowHzd(row)" v-if="row.bkZt == '05'">回执单</el-link>
<el-link type="primary" size="small" @click="handleAdd('detail', row)">详情</el-link> <el-link type="primary" size="small" @click="handleAdd('detail', row)">详情</el-link>
<el-link type="danger" size="small" @click="handleRow(row.id)" <el-link type="danger" size="small" @click="handleRow(row.id)"
v-if="['01', '03', '06'].includes(row.bkZt)">删除</el-link> v-if="['01', '03', '06'].includes(row.bkZt)">删除</el-link>

View File

@ -26,7 +26,6 @@
</div> </div>
<div class="mid"> <div class="mid">
<div class="left"> <div class="left">
<!-- <div class="title ellipsis">参会人员{{ item.chry }}</div> -->
<div class="desc"> <div class="desc">
<div class="info ellipsis" v-for="(el, i) in item.xsplList" :key="i">{{ i + 1 }}{{ el.plnr }}</div> <div class="info ellipsis" v-for="(el, i) in item.xsplList" :key="i">{{ i + 1 }}{{ el.plnr }}</div>
</div> </div>

View File

@ -0,0 +1,89 @@
<template>
<div>
<el-dialog :model-value="modelValue" :destroy-on-close="true" :title="title" @close="close"
:close-on-click-modal="true">
<div style="height: 50vh;overflow: auto;">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="150px" ref="elform">
</FormMessage>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="close">取消</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, getCurrentInstance, watch } from 'vue'
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { gsxtWlyqSelectById } from '@/api/semanticAnalysis.js'
const { proxy } = getCurrentInstance();
const { GA_D_ASJLYFLDM, GA_D_XSAJLBDM, BD_D_BJFSDM, GA_D_SACSFLDM, GA_D_DYLBDM } = proxy.$fzdict('GA_D_ASJLYFLDM', 'GA_D_XSAJLBDM', 'BD_D_BJFSDM', 'GA_D_SACSFLDM', 'GA_D_DYLBDM')
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
title: {
type: String,
default: '舆情详情'
},
dataList: {
type: Object,
default: () => { }
}, lx: {
type: String,
default: '1'
}
})
const emits = defineEmits(['update:modelValue'])
const listQuery = ref({})
const xsaj = [
{ label: "信息标题", prop: "xxbt", type: "textarea", width: "90%" },
{ label: "摘要", prop: "zy", type: "textarea" , width: "90%"},
{ label: "作者昵称", prop: "zznc", type: "input" },
{ label: "粉丝量", prop: "fsl", type: "input" },
{ label: "作者主页", prop: "zzzy", type: "input" },
{ label: "阅读数", prop: "yds", type: "input" },
{ label: "来源平台", prop: "lypt", type: "input" },
{ label: "转发数", prop: "zfs", type: "input" },
{ label: "关键词", prop: "gjc", type: "input"},
{ label: "是否藏语", prop: "sfzy", type: "input" },
{ label: "是否精选舆情", prop: "sfjx", type: "input" },
{ label: "情感倾向", prop: "qgqx", type: "input" },
{ label: "签到地", prop: "qdd", type: "input" },
{ label: "评论数", prop: "pls", type: "input" },
{ label: "内容涉及地域", prop: "nrsjdy", type: "input" },
{ label: "发布时间", prop: "fbsj", type: "input" },
{ label: "发布地", prop: "fbd", type: "input" },
{ label: "点赞数", prop: "dzs", type: "input" },
{ label: "所属部门", prop: "ssbm", type: "input" },
{ label: "所属县公安局", prop: "ssxgaj", type: "input" },
{ label: "所属市公安局", prop: "sssgaj", type: "input" },
{ label: "备注", prop: "bz", type: "textarea", width: "90%" },
]
const formData = ref()
const elform = ref()
watch(() => props.modelValue, (val) => {
if (val) {
console.log(props.dataList);
formData.value=xsaj
tbJqIdFunc()
}
})
const tbJqIdFunc = () => {
gsxtWlyqSelectById(props.dataList.id).then((res) => {
listQuery.value = res
})
}
const close = () => {
elform.value.reset()
emits('update:modelValue', false)
}
</script>

View File

@ -1,6 +1,8 @@
<template> <template>
<div> <div>
<el-dialog :model-value="modelValue" :destroy-on-close="true" :title="title" @close="close" :close-on-click-modal="true"> <el-dialog :model-value="modelValue" :destroy-on-close="true" :title="title" @close="close"
:close-on-click-modal="true">
{{ getData }}
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules"> <FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform" :rules="rules">
<template #chryList> <template #chryList>
<el-input v-model="chryList" clearable placeholder="请选择参会人员" @click="isShowDialog = true" <el-input v-model="chryList" clearable placeholder="请选择参会人员" @click="isShowDialog = true"
@ -24,6 +26,7 @@ import { ref, reactive, computed, getCurrentInstance } from 'vue'
import FormMessage from "@/components/aboutTable/FormMessage.vue"; import FormMessage from "@/components/aboutTable/FormMessage.vue";
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue" import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue"
import { wshsAdd } from "@/api/huiShangyp/tacticalApi" import { wshsAdd } from "@/api/huiShangyp/tacticalApi"
import { qcckGet, qcckPost } from "@/api/qcckApi.js"
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
@ -58,9 +61,11 @@ const rules = reactive({
] ]
}) })
const getData = computed(() => { const getData = computed(() => {
console.log(props.dataList, "测试");
return { return {
glxsid: props.dataList.glzjjdbh || props.dataList.asjbh, glxsid: props.dataList.glzjjdbh || props.dataList.asjbh,
glxsmc: props.dataList.ajmc || props.dataList.bjrmc glxsmc: props.dataList.ajmc ||props.dataList.bcjjnr|| props.dataList.bjrmc
} }
}) })
const listQuery = ref({}) const listQuery = ref({})
@ -80,6 +85,25 @@ const close = () => {
const submit = () => { const submit = () => {
elform.value.submit((val) => { elform.value.submit((val) => {
if (val) { if (val) {
let url
switch (props.lx) {
case '01':
const dadta = {
...listQuery.value,
...getData.value,
lylx: props.lx
}
url = '/mosty-gsxt/lzJcjPjdb/createwWshs'
qcckPost(dadta, url).then(res => {
proxy.$message({
message: '添加成功',
type: 'success'
})
emits('update:modelValue', false)
})
break;
default:
const promes = { const promes = {
...listQuery.value, ...listQuery.value,
...getData.value ...getData.value
@ -91,6 +115,11 @@ const submit = () => {
}) })
emits('update:modelValue', false) emits('update:modelValue', false)
}) })
break;
}
} }
}) })

View File

@ -74,6 +74,9 @@
<template #jjdbh="{ row }"> <template #jjdbh="{ row }">
<span @click="jqDetail(row)">{{ row.jjdbh }}</span> <span @click="jqDetail(row)">{{ row.jjdbh }}</span>
</template> </template>
<template #xxbt="{ row }">
<span @click="openPublicOpinionDialog(row)">{{ row.xxbt }}</span>
</template>
<template #asjbh="{ row }"> <template #asjbh="{ row }">
<span @click="caseDetail(row, row.lx)">{{ row.asjbh }}</span> <span @click="caseDetail(row, row.lx)">{{ row.asjbh }}</span>
</template> </template>
@ -104,11 +107,12 @@
<JudgmentReport v-model="visible" :search="search" :xzlx="xzlx"></JudgmentReport> <JudgmentReport v-model="visible" :search="search" :xzlx="xzlx"></JudgmentReport>
<DiscussionDialog v-model="showDialog" :dataList="dataList" :lx="lx" /> <DiscussionDialog v-model="showDialog" :dataList="dataList" :lx="lx" />
<PoliceIncidentDetails v-model="showJqDetail" :dataList="dataList" title="警情详情" /> <PoliceIncidentDetails v-model="showJqDetail" :dataList="dataList" title="警情详情" />
<PublicOpinionDialog v-model="showPublicOpinionDialog" :dataList="dataList" />"
<CaseDetails v-model="showCaseDetail" :dataList="dataList" title="案件详情" :lx="ajlx" /> <CaseDetails v-model="showCaseDetail" :dataList="dataList" title="案件详情" :lx="ajlx" />
</template> </template>
<script setup> <script setup>
import { lzJcjPjdbSelectPage } from '@/api/semanticAnalysis.js' import { lzJcjPjdbSelectPage, gsxtWlyqGetPageList, } from '@/api/semanticAnalysis.js'
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import JudgmentReport from './components/judgmentReport.vue' import JudgmentReport from './components/judgmentReport.vue'
import { qcckPost, qcckGet } from "@/api/qcckApi.js"; import { qcckPost, qcckGet } from "@/api/qcckApi.js";
@ -120,6 +124,7 @@ import { useRoute, useRouter } from 'vue-router';
import { tbJqGetPageList, xsajSelectPage, xzajSelectPage } from '@/api/yj.js' import { tbJqGetPageList, xsajSelectPage, xzajSelectPage } from '@/api/yj.js'
import DiscussionDialog from './components/discussionDialog.vue'; import DiscussionDialog from './components/discussionDialog.vue';
import PoliceIncidentDetails from './components/policeIncidentDetails.vue'; import PoliceIncidentDetails from './components/policeIncidentDetails.vue';
import PublicOpinionDialog from './components/PublicOpinionDialog.vue';
import CaseDetails from './components/caseDetails.vue'; import CaseDetails from './components/caseDetails.vue';
const router = useRouter(); const router = useRouter();
import { nextTick, onMounted, reactive, getCurrentInstance, ref, watch } from 'vue'; import { nextTick, onMounted, reactive, getCurrentInstance, ref, watch } from 'vue';
@ -193,13 +198,13 @@ const list = reactive([
pageConfiger: { pageConfiger: {
page: 1, page: 1,
total: 0, total: 0,
pageSize: 6, pageSize: 10,
}, },
tableColumn: [ tableColumn: [
{ label: "舆情标题", prop: "yqbt", showOverflowTooltip: true }, { label: "舆情标题", prop: "xxbt", showOverflowTooltip: true, showSolt: true },
{ label: "舆情内容", prop: "yqnr", showOverflowTooltip: true }, { label: "昵称", prop: "zznc", showOverflowTooltip: true },
{ label: "舆情来源", prop: "yqly", showOverflowTooltip: true }, { label: "来源平台", prop: "lypt", showOverflowTooltip: true },
{ label: "舆情时间", prop: "yqsj", showOverflowTooltip: true }, { label: "发布时间", prop: "fbsj", showOverflowTooltip: true },
], ],
}, },
{ {
@ -286,6 +291,7 @@ onMounted(() => {
tabHeightFn() tabHeightFn()
getJqList() //警情列表 getJqList() //警情列表
getAjList()//案件列表 getAjList()//案件列表
getgsxtWlyqGetPageList()//网络舆情列表
}); });
@ -336,6 +342,7 @@ const onSearch = () => {
switch (xzlx.value) { switch (xzlx.value) {
case '01': case '01':
getgsxtWlyqGetPageList()
break; break;
case '02': case '02':
getJqList() getJqList()
@ -399,6 +406,29 @@ const getAjList = () => {
}) })
} }
} }
// 网络舆情
const getgsxtWlyqGetPageList = () => {
let params = {
pageCurrent: list[0].pageConfiger.page,
pageSize: list[0].pageConfiger.pageSize,
startTime: dataSearch.value.startTime,
endTime: dataSearch.value.endTime,
}
gsxtWlyqGetPageList(params).then(res => {
console.log(res);
list[0].tableList = res.records.map(item => {
return {
...item,
}
}) || [];
list[0].pageConfiger.total = res.total;
})
}
// 网上会商 // 网上会商
const showDialog = ref(false) const showDialog = ref(false)
const dataList = ref() const dataList = ref()
@ -459,6 +489,7 @@ const changeNo = (e, type) => {
switch (type) { switch (type) {
case '网络舆情': case '网络舆情':
list[0].pageConfiger.page = e; list[0].pageConfiger.page = e;
getgsxtWlyqGetPageList()
break; break;
case '警情': case '警情':
list[1].pageConfiger.page = e; list[1].pageConfiger.page = e;
@ -479,6 +510,7 @@ const changeSize = (e, type) => {
switch (type) { switch (type) {
case '网络舆情': case '网络舆情':
list[0].pageConfiger.pageSize = e; list[0].pageConfiger.pageSize = e;
getgsxtWlyqGetPageList()
break; break;
case '警情': case '警情':
list[1].pageConfiger.pageSize = e; list[1].pageConfiger.pageSize = e;
@ -549,19 +581,11 @@ const handleYP = () => {
default: default:
break; break;
} }
}
const showPublicOpinionDialog = ref(false)
const openPublicOpinionDialog = (row) => {
showPublicOpinionDialog.value = true
dataList.value = {...row}
} }
// 表格高度计算 // 表格高度计算

View File

@ -0,0 +1,49 @@
<template>
<div class="detail_box">
<el-descriptions title="审核详情信息" border>
<el-descriptions-item :rowspan="2" label="研判名称" >{{detail.ypmc}}</el-descriptions-item>
<el-descriptions-item label="报告名称">{{detail.bgmc}}</el-descriptions-item>
<el-descriptions-item label="所属部门">{{ detail.ssbm }}</el-descriptions-item>
<el-descriptions-item label="报告类型"><DictTag :tag="false" :value="detail.bglx" :options="D_BZ_YPLX" /></el-descriptions-item>
<el-descriptions-item label="审核状态"><DictTag :tag="false" :value="detail.shzt" :options="D_BZ_XSSHZT" /></el-descriptions-item>
<el-descriptions-item label="创建人姓名">{{ detail.cjrxm }}</el-descriptions-item>
<el-descriptions-item label="创建人身份证号">{{ detail.cjrsfzh }}</el-descriptions-item>
<el-descriptions-item label="报告内容">{{ detail.bgnr }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue'
import { useRoute } from 'vue-router'
import { qcckGet } from "@/api/qcckApi.js";
const { proxy } = getCurrentInstance();
const { D_BZ_YPLX ,D_BZ_XSSHZT } = proxy.$dict('D_BZ_YPFS',"D_BZ_YPLX" ,'D_BZ_XSSHZT')
const route = useRoute();
const detail = ref({});
onMounted(() => {
getDetail();
})
const getDetail = () => {
qcckGet({}, "/mosty-gsxt/gsxtYpbg/" + route.query.id).then((res) => {
detail.value = res || {};
console.log(detail.value);
})
}
</script>
<style lang="scss" scoped>
.detail_box {
padding: 20px 10vw;
box-sizing: border-box;
width: 100%;
height: 100vh;
overflow: hidden;
overflow-y: auto;
}
</style>

View File

@ -0,0 +1,186 @@
<template>
<div>
<!-- 搜索 -->
<div ref="searchBox" class="mt10 mb10">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<!-- 表格 -->
<div class="tabBox" :style="{height: pageData.tableHeight + 10 +'px'}">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bglx="{ row }">
<DictTag :tag="false" :value="row.bglx" :options="D_BZ_YPLX" />
</template>
<template #shzt="{ row }">
<DictTag :tag="false" :value="row.shzt" :options="D_BZ_XSSHZT" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('detail', row)">详情</el-link>
<el-link type="danger" ref="buttonRef" @click="showPopover(row)">审核</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="{ ...pageData.pageConfiger, total: pageData.total }"
/>
</div>
<!-- 详情 -->
<Detail bglx="02" ref="detailDiloag" :dict="{ D_BZ_YPFS, D_BZ_YPLX }"/>
</div>
</template>
<script setup>
import Detail from "@/views/backOfficeSystem/JudgmentHome/strategicResearch/addReport.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import { useRouter } from 'vue-router';
const router = useRouter();
const { proxy } = getCurrentInstance();
const { D_BZ_YPFS,D_BZ_YPLX ,D_BZ_XSSHZT } = proxy.$dict('D_GZL_SHZT','D_BZ_YPFS',"D_BZ_YPLX" ,'D_BZ_XSSHZT')
const detailDiloag = ref();
const searchBox = ref(); //搜索框
const searchConfiger = ref([
{
label: "研判名称",
prop: "ypmc",
placeholder: "请输入研判名称",
showType: "input"
},
{
label: "报告名称",
prop: "bgmc",
placeholder: "请输入报告名称",
showType: "input"
},
{
label: "所属部门",
prop: "ssbmdm",
placeholder: "请选择所属部门",
showType: "department",
},
{
label: "报告类型",
prop: "bglx",
placeholder: "请选择报告类型",
showType: "select",
options: D_BZ_YPLX
},
{
label: "审核状态",
prop: "shzt",
placeholder: "请选择审核状态",
showType: "select",
options: D_BZ_XSSHZT
},
]);
const queryFrom = ref({});
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
{
label: "研判名称",
prop: "ypmc"
},
{
label: "报告名称",
prop: "bgmc"
},{
label: "所属部门",
prop: "ssbm"
},
{
label: "报告类型",
prop: "bglx",
showSolt: true,
},
{
label: "审核状态",
prop: "shzt",
showSolt: true,
},
]
});
onMounted(() => {
tabHeightFn();
getList();
});
// 搜索
const onSearch = (val) => {
queryFrom.value = { ...val };
pageData.pageConfiger.pageCurrent = 1;
getList();
};
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
const getList = () => {
pageData.tableConfiger.loading = true;
let params = {
...queryFrom.value,
pageCurrent:pageData.pageConfiger.pageCurrent,
pageSize:pageData.pageConfiger.pageSize
}
qcckGet(params, "/mosty-gsxt/gsxtYpbg/queryShList").then((res) => {
pageData.tableData = res.records;
pageData.total = res.total;
pageData.tableConfiger.loading = false;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 详情
const addEdit = (type, row) => {
detailDiloag.value.init(type, row)
};
const showPopover = (row) => {
const url = router.resolve({ path: '/ReviewListSH', query:{id:row.id} });
window.open(url.href, '_blank');
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 210;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
</style>

View File

@ -16,13 +16,14 @@
<el-table-column prop="ypbmmc" label="部门" width="150" align="center" /> <el-table-column prop="ypbmmc" label="部门" width="150" align="center" />
<el-table-column label="素材要求" align="center"> <el-table-column label="素材要求" align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-input v-model="row.scyq" type="textarea" :rows="4" :disabled="isDetail || !isShiQingBaoZhongXin" placeholder="请输入研判素材" /> <el-input v-model="row.scyq" type="textarea" :rows="4" :disabled="isDetail || !isShiQingBaoZhongXin"
placeholder="请输入研判素材" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="附件" align="center"> <el-table-column label="附件" align="center">
<template #default="{ row }"> <template #default="{ row }">
<UploadFile v-model="row.fj" :disabled="isDetail || (!isShiQingBaoZhongXin && !isAdd)" :limit="1" :isImg="false" <UploadFile v-model="row.fj" :disabled="isDetail || (!isShiQingBaoZhongXin && !isAdd)" :limit="1"
:isAll="true" /> :isImg="false" :isAll="true" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="wcqk" label="完成状态" width="80" align="center"> <el-table-column prop="wcqk" label="完成状态" width="80" align="center">
@ -32,7 +33,7 @@
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="180" align="center"> <!-- <el-table-column label="操作" width="180" align="center">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="text" size="small" @click="updateStatus(row)" :disabled="updateDis(row)"> <el-button type="text" size="small" @click="updateStatus(row)" :disabled="updateDis(row)">
@ -42,16 +43,16 @@
提交素材 提交素材
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column> -->
</el-table> </el-table>
</div> </div>
</template> </template>
</FormMessage> </FormMessage>
</div> </div>
<!-- 底部按钮 --> <!-- 底部按钮 -->
<div class="bottom-actions" v-if="title !== '新增' && listQuery.id && listQuery.ssbmdm == userInfo.deptCode" > <div class="bottom-actions" v-if="title !== '新增' && listQuery.id && listQuery.ssbmdm == userInfo.deptCode">
<el-button type="primary" size="small" @click="sendNotice" :loading="noticeLoading">下发通知</el-button> <el-button type="primary" size="small" @click="sendNotice" :loading="noticeLoading">下发通知</el-button>
<el-button type="success" size="small" @click="confirmJudgment" :loading="confirmLoading">确认研判</el-button> <!-- <el-button type="success" size="small" @click="confirmJudgment" :loading="confirmLoading">确认研判</el-button> -->
</div> </div>
</div> </div>
@ -148,20 +149,28 @@ const confirmLoading = ref(false) // 确认研判加载状态
const rules = reactive({ const rules = reactive({
// 可以在这里添加表单验证规则 // 可以在这里添加表单验证规则
ypsj: [
{ required: true, message: '请选择约稿时间', trigger: 'change' }
],
jzsj:[ { required: true, message: '请选择截止时间', trigger: 'change' }]
}); });
watch(() => props.dict, (val) => { watch(() => props.dict, (val) => {
if (val) { if (val) {
formData.value = [ formData.value = [
{ label: "研判议题", prop: "ypyt", type: "input", width: '48%', disabled: isDetail.value }, // { label: "研判议题", prop: "ypyt", type: "input", width: '48%', disabled: isDetail.value },
{ label: "研判时间", prop: "ypsj", type: "datetime", width: '48%' , disabled: isDetail.value }, { label: "约稿时间", prop: "ypsj", type: "datetime", width: '48%', disabled: isDetail.value },
{ label: "报告类型", prop: "bglx", type: "radio", options: props.dict.D_BZ_YPLX, width: '48%' , disabled: isDetail.value }, { label: "截止时间", prop: "jzsj", type: "datetime", width: '48%', disabled: isDetail.value },
{ label: "研判方式", prop: "ypfs", type: "radio", options: props.dict.D_BZ_YPFS, width: '48%' , disabled: isDetail.value }, // { label: "报告类型", prop: "bglx", type: "radio", options: props.dict.D_BZ_YPLX, width: '48%' , disabled: isDetail.value },
{ label: "参与研判部门", prop: "jsdxBmDm", type: "department", multiple: true, depMc: 'jsdxBmMc', width: '48%' , disabled: isDetail.value }, // { label: "研判方式", prop: "ypfs", type: "radio", options: props.dict.D_BZ_YPFS, width: '48%' , disabled: isDetail.value },
{ label: "研判要求", prop: "ypyq", type: "textarea", width: '100%' , disabled: isDetail.value }, { label: "约稿部门", prop: "jsdxBmDm", type: "department", multiple: true, depMc: 'jsdxBmMc', width: '48%', disabled: isDetail.value },
{ label: "约稿要求", prop: "ypyq", type: "textarea", width: '100%', disabled: isDetail.value },
{ label: "列表", prop: "bmList", type: "slot", width: '100%' }, { label: "列表", prop: "bmList", type: "slot", width: '100%' },
] ]
} }
}) })
/** 是否修改禁用 */ /** 是否修改禁用 */
function updateDis(row) { function updateDis(row) {
/** 无id 禁用 */ /** 无id 禁用 */
@ -461,6 +470,7 @@ defineExpose({ init });
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
// z-index: 1000; // z-index: 1000;
} }
.table-box { .table-box {
// width: calc(100% - 2px); // width: calc(100% - 2px);
width: 100%; width: 100%;

View File

@ -26,9 +26,11 @@
</template> </template>
<!-- 操作 --> <!-- 操作 -->
<template #controls="{ row }"> <template #controls="{ row }">
<el-link size="small" type="primary" @click="getDataById('edit', row)" :disabled="userInfo.deptCode!=row.ssbmdm">修改</el-link> <el-link size="small" type="primary" @click="getDataById('edit', row)"
:disabled="userInfo.deptCode != row.ssbmdm">修改</el-link>
<el-link size="small" type="primary" @click="getDataById('detail', row)">详情</el-link> <el-link size="small" type="primary" @click="getDataById('detail', row)">详情</el-link>
<el-link size="small" type="danger" @click="deleteFile(row)" :disabled="userInfo.deptCode!=row.ssbmdm">删除</el-link> <el-link size="small" type="danger" @click="deleteFile(row)"
:disabled="userInfo.deptCode != row.ssbmdm">删除</el-link>
</template> </template>
</MyTable> </MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{ <Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
@ -48,7 +50,7 @@ import Search from "@/components/aboutTable/Search.vue";
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { getItem } from "@/utils/storage.js"; import { getItem } from "@/utils/storage.js";
import { sjzlGetPageList, sjzldeleteEntity } from "@/api/yj.js"; import { sjzlGetPageList, sjzldeleteEntity } from "@/api/yj.js";
import { reactive, ref, onMounted, getCurrentInstance, watch,computed } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, watch, computed } from "vue";
import AddForm from "./addForm.vue"; import AddForm from "./addForm.vue";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { D_BZ_YPFS, D_BZ_YPLX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX") const { D_BZ_YPFS, D_BZ_YPLX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX")
@ -57,7 +59,7 @@ const searchBox = ref(); //搜索框
const userInfo = ref({}) const userInfo = ref({})
onMounted(() => { onMounted(() => {
userInfo.value = getItem('deptId')?getItem('deptId')[0]:{} userInfo.value = getItem('deptId') ? getItem('deptId')[0] : {}
tabHeightFn() tabHeightFn()
if (route.query.id) { if (route.query.id) {
detailDiloag.value.init('edit', { detailDiloag.value.init('edit', {
@ -77,7 +79,8 @@ const isShiQingBaoZhongXin = computed(() => {
}) })
const searchConfiger = ref([ const searchConfiger = ref([
{ label: "研判议题", prop: 'ypyt', placeholder: "请输入研判议题", showType: "input" }, { label: "约稿时间", prop: 'startTime', placeholder: "请输入约稿时间", showType: "datetimerange" },
{ label: "约稿要求", prop: 'ypyq', placeholder: "请输入约稿要求", showType: "input" },
// { label: "研判方式", prop: 'ypfs', placeholder: "请输入研判方式", showType: "radio",options:D_BZ_YPFS }, // { label: "研判方式", prop: 'ypfs', placeholder: "请输入研判方式", showType: "radio",options:D_BZ_YPFS },
]); ]);
@ -96,11 +99,12 @@ const pageData = reactive({
}, },
controlsWidth: 240, controlsWidth: 240,
tableColumn: [ tableColumn: [
{ label: "研判议题", prop: "ypyt" }, // { label: "研判议题", prop: "ypyt" },
{ label: "研判方式", prop: "ypfs", showSolt: true }, // { label: 方式", prop: "ypfs", showSolt: true },
{ label: "报告类型", prop: "bglx", showSolt: true }, // { label: "报告类型", prop: "bglx", showSolt: true },
{ label: "研判时间", prop: "ypsj" }, { label: "约稿时间", prop: "ypsj" },
{ label: "研判要求", prop: "ypyq" }, { label: "截止时间", prop: "jzsj" },
{ label: "约稿要求", prop: "ypyq" },
{ label: "发起部门", prop: "ssbm" }, { label: "发起部门", prop: "ssbm" },
] ]
}); });
@ -111,6 +115,8 @@ const onSearch = (val) => {
const promes = { const promes = {
...val, ...val,
...pageData.pageConfiger, ...pageData.pageConfiger,
startTime: val.startTime ? val.startTime[0] : '',
endTime: val.startTime ? val.startTime[1] : '',
} }
queryFrom.value = { ...promes } queryFrom.value = { ...promes }
pageData.pageConfiger.pageCurrent = 1; pageData.pageConfiger.pageCurrent = 1;

View File

@ -11,7 +11,6 @@
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules"> <FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
</FormMessage> </FormMessage>
</div> </div>
</div> </div>
</template> </template>
@ -21,11 +20,12 @@ import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch, computed } from "vue"; import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch, computed } from "vue";
import { addJudgmentCommandList, editJudgmentCommand, getJudgmentCommandDetail } from "@/api/huiShangyp/judgmentCommand.js" import { addJudgmentCommandList, editJudgmentCommand, getJudgmentCommandDetail } from "@/api/huiShangyp/judgmentCommand.js"
// import { getItem } from '@//utils/storage.js' // import { getItem } from '@//utils/storage.js'
import { useRouter } from 'vue-router'
const emit = defineEmits(["updateDate", "getList"]); const emit = defineEmits(["updateDate", "getList"]);
const props = defineProps({ const props = defineProps({
dict: Object dict: Object
}); });
const router = useRouter()
const imgMsg = ref([]) const imgMsg = ref([])
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗 const dialogForm = ref(false); //弹窗
@ -118,6 +118,7 @@ const close = () => {
listQuery.value = {}; listQuery.value = {};
dialogForm.value = false; dialogForm.value = false;
loading.value = false; loading.value = false;
router.replace({ path: '/judgmentCommand' })// 移除id 避免刷新一直带参数
}; };
defineExpose({ init }); defineExpose({ init });

View File

@ -61,18 +61,11 @@ import FeedbackDialog from "./components/FeedbackDialog.vue";
import { getItem } from '@//utils/storage.js' import { getItem } from '@//utils/storage.js'
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { D_BZ_YPFS, D_BZ_YPLX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX") const { D_BZ_YPFS, D_BZ_YPLX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX")
const detailDiloag = ref();
const searchBox = ref(); //搜索框 const searchBox = ref(); //搜索框
const userInfo = ref() const userInfo = ref()
onMounted(() => { onMounted(() => {
userInfo.value = getItem('deptId')[0] userInfo.value = getItem('deptId')[0]
tabHeightFn() tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', {
id: route.query.id
});
return
}
getList() getList()
}); });
@ -149,8 +142,13 @@ const tabHeightFn = () => {
}; };
}; };
const route = useRoute() const route = useRoute()
const addForm = ref(null) const addForm = ref(null)
watch(() => route.query.id, (val) => {
console.log('val: ', val);
if (val) {
addForm.value.init('detail', {id:val}, '01');
}
},{deep:true});
const feedbackDialog = ref(false) const feedbackDialog = ref(false)
const currentFeedbackRow = ref({}) const currentFeedbackRow = ref({})
const getDataById = (type, row) => { const getDataById = (type, row) => {

View File

@ -98,7 +98,7 @@
* @property {Array} fj - 附件数组 * @property {Array} fj - 附件数组
* @property {string} wcqk - 完成情况01 准备中、02 已完成) * @property {string} wcqk - 完成情况01 准备中、02 已完成)
*/ */
import { qcckGet } from "@/api/qcckApi.js";
import FormMessage from "@/components/aboutTable/FormMessage.vue"; import FormMessage from "@/components/aboutTable/FormMessage.vue";
import UploadFile from "@/components/MyComponents/Upload/index.vue"; import UploadFile from "@/components/MyComponents/Upload/index.vue";
// import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue" // import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue"
@ -214,12 +214,13 @@ watch(() => listQuery.value.jsdxBmDm, (val) => {
}) })
}) })
// 初始化数据 // 初始化数据
const init = (type, row, wjlb) => { const init = (type, row, wjlb) => {
dialogForm.value = true; dialogForm.value = true;
title.value = type == "add" ? "新增" : type == "edit" ? "编辑" : "详情"; title.value = type == "add" ? "新增" : type == "edit" ? "编辑" : "详情";
outRow.value = row outRow.value = row
if (row) { if (row) {
getDataById(row.id) getDataById(row.id )
} else { } else {
listQuery.value = { listQuery.value = {
bglx: props.bglx, // 报告类型 01 战术研判 02战略研判 bglx: props.bglx, // 报告类型 01 战术研判 02战略研判
@ -232,7 +233,7 @@ const init = (type, row, wjlb) => {
}; };
// 根据id查询详情 // 根据id查询详情
const getDataById = (id) => { const getDataById = (id) => {
sjzlGetInfo(id).then((res) => { qcckGet({},'/mosty-gsxt/gsxtYpbg/'+id).then((res) => {
listQuery.value = res || {}; listQuery.value = res || {};
/** @type {Array<JudgmentDept>} 参与研判部门数据数组 */ /** @type {Array<JudgmentDept>} 参与研判部门数据数组 */
const cyypList = Array.isArray(res.cyypList) ? res.cyypList : [] const cyypList = Array.isArray(res.cyypList) ? res.cyypList : []

View File

@ -3,31 +3,32 @@
<div class="head_box"> <div class="head_box">
<span class="title">报告{{ title }} </span> <span class="title">报告{{ title }} </span>
<div> <div>
<el-button type="primary" size="small" :loading="loading" @click="submit">保存</el-button> <el-button type="primary" size="small" :loading="loading" @click="submit" v-if="title!='详情'">保存</el-button>
<el-button size="small" @click="close">关闭</el-button> <el-button size="small" @click="close">关闭</el-button>
</div> </div>
</div> </div>
<div class="form_cnt"> <div class="form_cnt">
<FormMessage :formList="formData" v-model="listQuery" ref="elform" :rules="rules"> <FormMessage :formList="formData" :disabled="title=='详情'" v-model="listQuery" ref="elform" :rules="rules">
<template #bgnr>
<el-input v-model="listQuery.bgnr" style="width: 100%" placeholder="请输入关键字" class="input-with-select">
<template #append>
<el-button :icon="Search" type="primary">搜索</el-button>
</template>
</el-input>
</template>
<template #fj><el-button type="primary" @click="showText = true">附件上传</el-button></template> <template #fj><el-button type="primary" @click="showText = true">附件上传</el-button></template>
</FormMessage> </FormMessage>
<div class="cntBox"> <div class="cntBox">
<!-- 工具栏 --> <!-- 工具栏 -->
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" <Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode" /> :mode="mode" />
<!-- 编辑器 --> <!-- 编辑器 -->
<Editor :style="`height: 480px; overflow-y: hidden`" :model-value="textContent" :defaultConfig="editorConfig" <Editor
:mode="mode" @onCreated="handleCreated" @onChange="handChange" /> :style="`height: 480px; overflow-y: hidden`"
v-model="textContent"
:defaultConfig="editorConfig"
:mode="mode"
@onCreated="handleCreated"
@onChange="handChange"
/>
</div> </div>
<div v-if="outRow.id" style="display: flex; justify-content: center;"> <div v-if="listQuery.id" style="display: flex; justify-content: center;">
<!-- <el-button style="display: block;" type="primary" @click="ConsultationShow = true">网上会商</el-button> --> <!-- <el-button style="display: block;" type="primary" @click="ConsultationShow = true">网上会商</el-button> -->
<el-button style="display: block;" type="primary" @click="downloadWithStyles(textContent)">下载</el-button> <el-button style="display: block;" type="primary" @click="downloadWithStyles(textContent)">下载</el-button>
</div> </div>
@ -46,21 +47,18 @@ import ExtractionText from "@/components/ExtractionText/index.vue";
import FormMessage from "@/components/aboutTable/FormMessage.vue"; import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js"; import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
import "@wangeditor/editor/dist/css/style.css"; import "@wangeditor/editor/dist/css/style.css";
import { useRoute, useRouter } from 'vue-router'
// import Consultation from './consultation.vue' // import Consultation from './consultation.vue'
import { Editor, Toolbar } from "@wangeditor/editor-for-vue"; import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, shallowRef, onBeforeUnmount, watch } from "vue"; import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, shallowRef, onBeforeUnmount, watch } from "vue";
import { gsxtYpbgAddEntity, gsxtYpbgEditEntity } from "@/api/huiShangyp/tacticalApi.js" import { gsxtYpbgAddEntity, gsxtYpbgEditEntity, gsxtYpbgId } from "@/api/huiShangyp/strategicApi.js"
const emit = defineEmits(["updateDate", 'ok']); const emit = defineEmits(["updateDate", 'ok']);
const props = defineProps({ const { proxy } = getCurrentInstance();
dic: Object, const { D_BZ_YPLX } = proxy.$dict("D_BZ_YPLX")
}); const props = defineProps({});
const ConsultationShow = ref(false) const ConsultationShow = ref(false)
const showText = ref(false); const showText = ref(false);
const textContent = ref() const textContent = ref()
const { proxy } = getCurrentInstance();
const editorRef = shallowRef(); const editorRef = shallowRef();
const dialogForm = ref(false); //弹窗 const dialogForm = ref(false); //弹窗
const mode = "default"; const mode = "default";
@ -110,75 +108,87 @@ const rules = reactive({
}); });
const formData = ref([ const formData = ref([
{ label: "报告名称", prop: "bgmc", type: "input", width: "100%", blur: setEditorTextContent }, { label: "报告名称", prop: "bgmc", type: "input", width: "100%", blur: setEditorTextContent },
{ label: "报告内容", prop: "bgnr", type: "slot", width: "100%", blur: setEditorTextContent }, {
// { label: "附件内容", prop: "fj", type: "slot", width: "100%" }, label: "报告类型", prop: "bglx", type: "select", width: "100%", options: D_BZ_YPLX
},
]); ]);
const listQuery = ref({ const listQuery = ref({}); //表单
bgmc: "",
bgnr: "",
fj: ""
}); //表单
const loading = ref(false); const loading = ref(false);
const elform = ref(); const elform = ref();
const title = ref(""); const title = ref("");
/** 外面行数据 */
const outRow = ref({})
// 初始化数据 // 初始化数据
const init = (type, reportData, row) => { const init = (type, row) => {
listQuery.value = {
bgmc: reportData.bgmc,
bgnr: reportData.bgnr,
id: reportData.id,
// fj: reportData.fj
}
outRow.value = { ...row }
dialogForm.value = true; dialogForm.value = true;
title.value = type == "add" ? "新增" : "编辑"; title.value = type == "add" ? "新增" :type == "edit"? "编辑" : "详情";
if (row) {
getDataById(row.id)
}
// listQuery.value = JSON.parse(JSON.stringify(row));
setEditorTextContent() setEditorTextContent()
}; };
const getText = (val, row = {}) => { // 根据id查询详情
const getDataById = (id) => {
qcckGet({},'/mosty-gsxt/gsxtYpbg/'+id).then((res) => {
listQuery.value = res || {};
// /** @type {Array<JudgmentDept>} 参与研判部门数据数组 */
// const cyypList = Array.isArray(res.cyypList) ? res.cyypList : []
// listQuery.value.jsdxBmDm = cyypList.map(item => {
// return item.ypbmdm
// })
// listQuery.value.jsdxBmMc = cyypList.map(item => {
// return item.ypbmmc
// })
});
};
const getText = (val) => {
listQuery.value.fj = val.text; listQuery.value.fj = val.text;
setEditorTextContent() setEditorTextContent()
} }
function setEditorTextContent() { function stripReportHeader(html) {
let html = dataBt.value; const source = typeof html === "string" ? html : "";
if (!source) return "";
const hrMatch = source.match(/<hr\b[^>]*\/?>/i);
html += `<p style="text-align: center;"><span style="font-size: 22px;">${listQuery.value.bgmc || ''}</span></p>` if (hrMatch && typeof hrMatch.index === "number") {
html += `<p>${listQuery.value.fj || ''}</p>` return source.slice(hrMatch.index + hrMatch[0].length).trim();
textContent.value = html }
if (typeof dataBt.value === "string" && source.startsWith(dataBt.value)) {
return source.slice(dataBt.value.length).trim();
}
return source.trim();
} }
// watch(() => listQuery.value, (val) => { function setEditorTextContent() {
let html = dataBt.value;
html += `<p style="text-align: center;"><span style="font-size: 22px;">${listQuery.value.bgnr || ''}</span></p>`
html += `<p>${listQuery.value.fj || ''}</p>`
textContent.value = html;
}
// },
// {
// deep: true, immediate: true
// })
// 提交 // 提交
const submit = () => { const submit = () => {
elform.value.submit((data) => { elform.value.submit( async (data) => {
// let url = title.value == "新增" ? "/mosty-gsxt/gsxt/jyfx/add" : "/mosty-gsxt/gsxt/jyfx/edit"; loading.value = true;
const params = {
let params = {
...data, ...data,
ypid: outRow.value.id, bgnr: stripReportHeader(textContent.value)
ypmc: outRow.value.ypyt
}; };
const apiFun = !listQuery.value.id ? gsxtYpbgAddEntity : gsxtYpbgEditEntity const apiFun = !listQuery.value.id ? gsxtYpbgAddEntity : gsxtYpbgEditEntity;
if (!listQuery.value.id) delete params.id if (!listQuery.value.id) delete params.id;
apiFun(params).then(() => { try {
await apiFun(params);
loading.value = false; loading.value = false;
proxy.$message({ type: "success", message: title.value + "成功" }); proxy.$message({ type: "success", message: title.value + "成功" });
emit("ok"); emit("ok");
close(); close();
}).catch(() => { } catch (e) {
loading.value = false; loading.value = false;
}) }
}); });
}; };
//编辑器创建成功 //编辑器创建成功
@ -187,22 +197,21 @@ const handleCreated = (editor) => {
}; };
//内容发生变化 //内容发生变化
const handChange = (editor) => { const handChange = (editor) => {
// 判断是否是一个空段落,是空就传空文本 // 判断是否是一个空段落,是空就传空文本
}; };
onBeforeUnmount(() => { onBeforeUnmount(() => {
const editor = editorRef.value; const editor = editorRef.value;
if (editor) editor.destroy(); if (editor) editor.destroy();
}); });
const router = useRouter();
// 关闭 // 关闭
const close = () => { const close = () => {
listQuery.value = {};
loading.value = false; loading.value = false;
dialogForm.value = false; dialogForm.value = false;
listQuery.value = {} listQuery.value = {}
router.replace({ path: '/strategicResearchs' })// 移除id 避免刷新一直带参数
}; };

View File

@ -7,11 +7,11 @@
</div> </div>
<PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5"> <PageTitle :malginLeft="10" :height="35" backgroundColor="#ffff" :marginBottom="5" :marginTop="5">
<template #left> <template #left>
<el-button size="small" type="primary" @click="selfCreateResearch('add')"> <el-button size="small" type="primary" @click="createReport('add')">
<el-icon style="vertical-align: middle"> <el-icon style="vertical-align: middle">
<CirclePlus /> <CirclePlus />
</el-icon> </el-icon>
<span style="vertical-align: middle">自建研判</span> <span style="vertical-align: middle">创建报告</span>
</el-button> </el-button>
</template> </template>
</PageTitle> </PageTitle>
@ -28,10 +28,12 @@
<!-- 操作 --> <!-- 操作 -->
<template #controls="{ row }"> <template #controls="{ row }">
<!-- <el-link size="small" type="primary" @click="getDataById('edit', row)">修改</el-link> --> <!-- <el-link size="small" type="primary" @click="getDataById('edit', row)">修改</el-link> -->
<el-link size="small" type="danger" @click="getypbgSjzlTjspId(row.id)">提交申请</el-link> <!-- <el-link size="small" type="danger" @click="getypbgSjzlTjspId(row.id)">提交申请</el-link> -->
<el-link size="small" type="primary" @click="getDataById('detail', row)">详情</el-link> <el-link size="small" type="warning" @click="handleRow(row)">送审</el-link>
<el-link size="small" type="primary" @click="createReport(row)">{{ row.ypbg?.id ? '编辑' : '创建' }}报告</el-link> <el-link size="small" type="primary" @click="createReport('edit', row)">编辑</el-link>
<el-link size="small" type="success" @click="createMeeting(row)">创建会议</el-link> <el-link size="small" type="primary" @click="createReport('detail', row)">详情</el-link>
<!-- <el-link size="small" type="success" @click="createMeeting(row)">创建会议</el-link>-->
<el-link size="small" type="danger" @click="deleteFile(row)">删除</el-link> <el-link size="small" type="danger" @click="deleteFile(row)">删除</el-link>
</template> </template>
</MyTable> </MyTable>
@ -44,46 +46,59 @@
<AddForm ref="addForm" :bglx="bglx" @getList="getList" :dict="{ D_BZ_YPFS, D_BZ_YPLX }" /> <AddForm ref="addForm" :bglx="bglx" @getList="getList" :dict="{ D_BZ_YPFS, D_BZ_YPLX }" />
<!-- 创建报告 --> <!-- 创建报告 -->
<addReport ref="reportTc" :row="currRow" :dic="{ D_GS_BQ_LX }" @ok="getList" /> <addReport ref="reportTc" :row="currRow" :dic="{ D_GS_BQ_LX,D_BZ_YPLX }" @ok="getList" />
<!-- 创建报告 --> <!-- 创建报告 -->
<addMeeting ref="meetingTc" :row="currRow" @updateDate="getList" /> <addMeeting ref="meetingTc" :row="currRow" @updateDate="getList" />
</template> </template>
<script setup> <script setup>
import { qcckGet } from "@/api/qcckApi";
import PageTitle from "@/components/aboutTable/PageTitle.vue"; import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue"; import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue"; import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue"; import Search from "@/components/aboutTable/Search.vue";
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { tacticalGet, strategicDelete } from "@/api/huiShangyp/tacticalApi.js";
import { reactive, ref, onMounted, getCurrentInstance, watch, computed, nextTick } from "vue"; import { reactive, ref, onMounted, getCurrentInstance, watch, computed, nextTick } from "vue";
import { ypbgSjzlTjspId } from "@/api/huiShangyp/strategicApi.js" import { ypbgSjzlTjspId,gsxtYpbgGetPageList ,gsxtYpbgDeleteEntity} from "@/api/huiShangyp/strategicApi.js"
import addReport from "./addReport.vue"; import addReport from "./addReport.vue";
import AddForm from "./addForm.vue"; import AddForm from "./addForm.vue";
import addMeeting from "./addMeeting.vue"; import addMeeting from "./addMeeting.vue";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { D_BZ_YPFS, D_BZ_YPLX, D_GS_BQ_LX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX", "D_GS_BQ_LX") const { D_BZ_YPFS, D_BZ_YPLX, D_GS_BQ_LX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX", "D_GS_BQ_LX")
/** 报告弹框 */ /** 报告弹框 */
const reportTc = ref(); const reportTc = ref();
/** 会议弹框 */ /** 会议弹框 */
const meetingTc = ref(); const meetingTc = ref();
const searchBox = ref(); //搜索框 const searchBox = ref(); //搜索框
const router = useRouter();
const route = useRoute(); const route = useRoute();
onMounted(() => { onMounted(() => {
tabHeightFn() tabHeightFn()
if (route.query.id) {
nextTick(() => {
addForm.value && addForm.value.init('edit', {
id: route.query.id
});
router.replace({ path: '/tacticalResearch' })// 移除id 避免刷新一直带参数
})
}
getList() getList()
}); });
watch(() => route.query.id, (val) => {
if (val) {
nextTick(() => {
reportTc.value && reportTc.value.init('edit', {
id: val
});
})
}
},{deep:true});
// 提交审核
const handleRow = (row) => {
proxy.$confirm('确定提交审核?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'}).then(() => {
qcckGet({},'/mosty-gsxt/gsxtYpbg/tjsp/'+row.id).then(res => {
proxy.$message.success('提交成功');
getList();
}).catch(() => {
proxy.$message.error('提交失败');
});
})
}
/** 是否市情报指挥中心 */ /** 是否市情报指挥中心 */
const isShiQingBaoZhongXin = computed(() => { const isShiQingBaoZhongXin = computed(() => {
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03' const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
@ -91,8 +106,8 @@ const isShiQingBaoZhongXin = computed(() => {
}) })
const searchConfiger = ref([ const searchConfiger = ref([
{ label: "研判议题", prop: 'ypyt', placeholder: "请输入研判议题", showType: "input" }, { label: "报告名称", prop: 'bgmc', placeholder: "请输入报告名称", showType: "input" },
// { label: "研判方式", prop: 'ypfs', placeholder: "请输入研判方式", showType: "radio",options:D_BZ_YPFS }, { label: "研判类型", prop: 'bglx', placeholder: "请输入研判类型", showType: "select",options:D_BZ_YPLX },
]); ]);
const pageData = reactive({ const pageData = reactive({
@ -100,7 +115,7 @@ const pageData = reactive({
keyCount: 0, keyCount: 0,
tableConfiger: { tableConfiger: {
rowHieght: 61, rowHieght: 61,
showSelectType: "checkBox", showSelectType: "null",
loading: false loading: false
}, },
total: 0, total: 0,
@ -110,12 +125,10 @@ const pageData = reactive({
}, },
controlsWidth: 240, controlsWidth: 240,
tableColumn: [ tableColumn: [
{ label: "研判议题", prop: "ypyt" }, { label: "报告名称", prop: "bgmc" },
{ label: "研判方式", prop: "ypfs", showSolt: true },
{ label: "报告类型", prop: "bglx", showSolt: true }, { label: "报告类型", prop: "bglx", showSolt: true },
{ label: "研判时间", prop: "ypsj" }, { label: "生成时间", prop: "scsj" },
{ label: "研判要求", prop: "ypyq" }, { label: "生成部门", prop: "ssbm" },
{ label: "发起部门", prop: "ssbm" },
] ]
}); });
@ -147,9 +160,10 @@ const changeSize = (val) => {
// 获取列表 // 获取列表
const getList = () => { const getList = () => {
pageData.tableConfiger.loading = true; pageData.tableConfiger.loading = true;
// bglx 报告类型01 战术研判 02 战略研判) // bglx 报告类型01 战术研判 02 战略研判), bglx: '02'
let data = { ...pageData.pageConfiger, ...queryFrom.value, bglx: '02' }; let data = { ...pageData.pageConfiger, ...queryFrom.value};
tacticalGet(data).then(res => { gsxtYpbgGetPageList(data).then(res => {
console.log(res);
pageData.tableData = res.records || []; pageData.tableData = res.records || [];
pageData.total = res.total; pageData.total = res.total;
pageData.tableConfiger.loading = false; pageData.tableConfiger.loading = false;
@ -177,7 +191,7 @@ const deleteFile = (row) => {
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
strategicDelete({ ids: [row.id] }).then(res => { gsxtYpbgDeleteEntity({ ids: [row.id] }).then(res => {
proxy.$message.success('删除成功'); proxy.$message.success('删除成功');
getList(); getList();
}).catch(() => { }).catch(() => {
@ -192,9 +206,8 @@ const selfCreateResearch = (type = 'add') => {
addForm.value.init(type, null, '01'); addForm.value.init(type, null, '01');
} }
/** 创建报告 */ /** 创建报告 */
const createReport = (row) => { const createReport = (type,row) => {
const type = !row.id ? 'add' : 'edit' reportTc.value.init(type, row)
reportTc.value.init(type, row?.ypbg || {}, row)
// currRow.value = { ...row } // currRow.value = { ...row }
// isShowReport.value = true // isShowReport.value = true
} }

View File

@ -171,6 +171,7 @@ const getDataById = (type, row) => {
addForm.value.init(type, row, '01'); addForm.value.init(type, row, '01');
} }
const deleteFile = (row) => { const deleteFile = (row) => {
proxy.$confirm('确定删除选中数据吗?', '提示', { proxy.$confirm('确定删除选中数据吗?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',

View File

@ -208,8 +208,6 @@ const createProcess = (row) => {
rowData.value = row rowData.value = row
} }
// 线索下发 // 线索下发
const xsxfShow = ref(false) const xsxfShow = ref(false)
const openXsxf = (row) => { const openXsxf = (row) => {

View File

@ -19,7 +19,7 @@
</FormMessage> </FormMessage>
</div> </div>
<div v-if="title == '详情'" class="timeline-container"> <div v-if="title == '详情'" class="timeline-container">
<el-timeline class="timeline-wrapper" v-if="listQuery.czlcLis&&listQuery.czlcList.length > 0"> <el-timeline class="timeline-wrapper" v-if="listQuery.czlcLis && listQuery.czlcList.length > 0">
<el-timeline-item placement="top" v-for="(activity, index) in listQuery.czlcList" :key="index" <el-timeline-item placement="top" v-for="(activity, index) in listQuery.czlcList" :key="index"
:timestamp="activity.czsj" :color="activity.czlx == '01' ? '#409eff' : '#67c23a'" size="large"> :timestamp="activity.czsj" :color="activity.czlx == '01' ? '#409eff' : '#67c23a'" size="large">
<div class="timeline-content" :class="activity.czlx == '01' ? 'sign-type' : 'feedback-type'"> <div class="timeline-content" :class="activity.czlx == '01' ? 'sign-type' : 'feedback-type'">
@ -50,16 +50,25 @@
import Xslist from '@/components/ChooseList/ChooseXs/index.vue' import Xslist from '@/components/ChooseList/ChooseXs/index.vue'
import FormMessage from '@/components/aboutTable/FormMessage.vue' import FormMessage from '@/components/aboutTable/FormMessage.vue'
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js"; import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
import { ref, defineExpose, reactive, onMounted, defineEmits, getCurrentInstance, nextTick } from "vue"; import { useRouter } from 'vue-router'
import { ref, defineExpose, reactive, onMounted, defineEmits, getCurrentInstance, nextTick ,watch} from "vue";
const emit = defineEmits(["updateDate"]); const emit = defineEmits(["updateDate"]);
const props = defineProps({ const props = defineProps({
dic: Object dic: {
type: Object,
default: () => ({})
}
}); });
const chooseVisible = ref(false) const chooseVisible = ref(false)
const roleIds = ref([]) const roleIds = ref([])
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗 const dialogForm = ref(false); //弹窗
const formData = ref([
const formData = ref()
watch(() => props.dic, (newVal) => {
if (newVal) {
formData.value = [
{ label: "指令标题", prop: "zlbt", type: "input", }, { label: "指令标题", prop: "zlbt", type: "input", },
{ label: "指令类型", prop: "zllx", type: "select", options: props.dic.D_GS_XS_ZLLX }, { label: "指令类型", prop: "zllx", type: "select", options: props.dic.D_GS_XS_ZLLX },
{ label: "指令等级", prop: "zldj", type: "select", options: props.dic.D_GS_ZDQT_FXDJ }, { label: "指令等级", prop: "zldj", type: "select", options: props.dic.D_GS_ZDQT_FXDJ },
@ -71,7 +80,10 @@ const formData = ref([
{ label: "抄送单位", prop: "csdw", type: "department" }, { label: "抄送单位", prop: "csdw", type: "department" },
{ label: "指令内容", prop: "zlnr", type: "textarea", width: '100%' }, { label: "指令内容", prop: "zlnr", type: "textarea", width: '100%' },
{ label: "附件", prop: "fjzd", type: "upload", width: '100%' }, { label: "附件", prop: "fjzd", type: "upload", width: '100%' },
]); ]
}
},{deep: true})
const listQuery = ref({}); //表单 const listQuery = ref({}); //表单
const loading = ref(false); const loading = ref(false);
const elform = ref(); const elform = ref();
@ -129,12 +141,13 @@ const submit = () => {
}).catch(() => { loading.value = false; }); }).catch(() => { loading.value = false; });
}); });
}; };
const router = useRouter()
// 关闭 // 关闭
const close = () => { const close = () => {
listQuery.value = {}; listQuery.value = {};
dialogForm.value = false; dialogForm.value = false;
loading.value = false; loading.value = false;
router.replace({ path: '/InstructionInformation' })// 移除id 避免刷新一直带参数
}; };
defineExpose({ init }); defineExpose({ init });
</script> </script>

View File

@ -58,8 +58,8 @@
></Pages> ></Pages>
</div> </div>
<!-- 详情 --> <!-- 详情 -->
<DetailForm ref="detailDiloag" v-if="isShow" @updateDate="getList" :dic="{D_GS_XS_ZLLX,D_GS_ZDQT_FXDJ}" />
</div> </div>
<DetailForm ref="detailDiloag" @updateDate="getList" :dic="{D_GS_XS_ZLLX,D_GS_ZDQT_FXDJ}" />
<Fk v-model="isShowFk" :dataList="dataList" @getList="getList"/> <Fk v-model="isShowFk" :dataList="dataList" @getList="getList"/>
</template> </template>
@ -71,7 +71,8 @@ import Search from "@/components/aboutTable/Search.vue";
import DetailForm from "./components/detailForm.vue"; import DetailForm from "./components/detailForm.vue";
import Fk from "./components/fk.vue"; import Fk from "./components/fk.vue";
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js"; import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue"; import { useRoute } from "vue-router";
import { reactive, ref, onMounted, getCurrentInstance, nextTick, watch } from "vue";
import { getItem } from '@/utils/storage' import { getItem } from '@/utils/storage'
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const {D_GS_XS_SJLY,D_GS_XS_ZLLX,D_GS_ZDQT_FXDJ,D_GS_XS_CZZT} = proxy.$dict('D_GS_XS_SJLY','D_GS_XS_ZLLX','D_GS_ZDQT_FXDJ','D_GS_XS_CZZT') const {D_GS_XS_SJLY,D_GS_XS_ZLLX,D_GS_ZDQT_FXDJ,D_GS_XS_CZZT} = proxy.$dict('D_GS_XS_SJLY','D_GS_XS_ZLLX','D_GS_ZDQT_FXDJ','D_GS_XS_CZZT')
@ -110,14 +111,20 @@ const pageData = reactive({
{ label: '是否反馈', prop: 'sffk', showSolt: true }, { label: '是否反馈', prop: 'sffk', showSolt: true },
{ label: '是否签收', prop: 'sfqs', showSolt: true }, { label: '是否签收', prop: 'sfqs', showSolt: true },
] ]
}); });
const route=useRoute()
const userInfo=ref(); const userInfo=ref();
onMounted(() => { onMounted(() => {
if (route.query.id) {
addEdit('detail', {id:route.query.id});
}
userInfo.value=getItem('deptId')[0] userInfo.value=getItem('deptId')[0]
getList() getList()
tabHeightFn(); tabHeightFn();
}); });
// 搜索 // 搜索
const onSearch = (val) =>{ const onSearch = (val) =>{
queryFrom.value = {...val} queryFrom.value = {...val}
@ -166,6 +173,12 @@ const addEdit = (type, row) => {
detailDiloag.value.init(type, row); detailDiloag.value.init(type, row);
}) })
}; };
watch(() => route.query.id, (val) => {
if (val) {
addEdit('detail', {id:route.query.id});
}
},{deep:true})
// 签收 // 签收
const signRow = (row) =>{ const signRow = (row) =>{
proxy.$confirm("确定要签收", "警告", {type: "warning"}).then(() => { proxy.$confirm("确定要签收", "警告", {type: "warning"}).then(() => {
@ -189,8 +202,6 @@ const fkRow = (row) => {
} }
const showBtn = (row) => { const showBtn = (row) => {
let item = row.xfbmList.find(v => v.ssbmdm == userInfo.value.deptCode) let item = row.xfbmList.find(v => v.ssbmdm == userInfo.value.deptCode)
console.log(item);
return item?true:false return item?true:false
// // if (item) { // // if (item) {
// // return item.zlzt == '01' ? 'sign' : item.zlzt == '02' ? 'feedback' : '' // // return item.zlzt == '01' ? 'sign' : item.zlzt == '02' ? 'feedback' : ''

Some files were not shown because too many files have changed in this diff Show More