This commit is contained in:
lcw
2025-11-28 22:25:58 +08:00
parent 85f1f3a6f7
commit e2a54c16eb
90 changed files with 2451 additions and 511 deletions

8
src/api/qbcj.js Normal file
View File

@ -0,0 +1,8 @@
import request from "@/utils/request";
const api = "/mosty-api/mosty-gsxt";
export const tbGsxtXscjTjForSjbm = (data) =>
request({
url: api + "/qbcj/getXscjTjForSjbm",
method: "post",
data
});

View File

@ -1,5 +1,6 @@
import request from "@/utils/request";
const api = "/qxda/api";
const api1 = "/mosty-api/mosty-gsxt";
export const ryxxJbxxSave = (params) => {
return request({
headers: {
@ -10,3 +11,37 @@ export const ryxxJbxxSave = (params) => {
params
});
};
// 获取档案完善接口
export const yjxxDawsAddEntity = (data) => {
return request({
url: api1 + "/yjxx/daws/addEntity",
method: "POST",
data
});
};
export const yjxxDawsGetPageList = (params) => {
return request({
url: api1 + `/yjxx/daws/selectList`,
method: "GET",
params
});
};
// 删除档案接口
export const yjxxDawsDeleteEntity = (data) => {
return request({
url: api1 + `/yjxx/daws/deleteEntity`,
method: "DELETE",
data
});
};
export const yjxxDawsUpdateEntity = (data) => {
return request({
url: api1 + `/yjxx/daws/editEntity`,
method: "PUT",
data
});
};
//

View File

@ -86,3 +86,33 @@ export const yjzxSfyjSelectList = (params) => {
params
})
}
// 行为预警
export const yjzxXwyjSelectList = (id) => {
return request({
url: api + `/yjzxXwyj/${id}`,
method: "get",
})
}
// 身份预警详情
export const yjzxyjzxSfyjSelectList = (id) => {
return request({
url: api + `/yjzxSfyj/${id}`,
method: "get",
})
}
// 组合预警详情
export const yjzxZhyjSelectList = (id) => {
return request({
url: api + `/yjzxZhyj/${id}`,
method: "get",
})
}
// /tbYjxx/yjzp 预警指派
export const tbYjxxYjzp = (data) => {
return request({
url: api + `/tbYjxx/yjzp`,
method: "POST",
data
})
}

View File

@ -44,7 +44,7 @@ import { getItem } from "@/utils/storage";
const conditionRoute = ref(true); //路况
const mMap = ref(null); //地图对象
const mapUtil = ref(null); //地图工具对象
const zoomTarget = ref(6);
const zoomTarget = ref(15);
const props = defineProps({
mapid: {

View File

@ -759,13 +759,13 @@ export function MapUtil(map) {
if (!data) return false;
// 使用传入的颜色参数,如果没有则使用默认值
const fillColorValue = fillColor || 'rgba(27, 205, 211, 0.3)';
const borderColorValue = borderColor || '#cf1010';
const borderColorValue = borderColor || 'rgba(209,112,65,1)';
const highlightColorValue = color || 'red';
// 创建多边形
const polygon = map.createPolygon(data, {
color: fillColorValue,
outLineColor: borderColorValue,
outLineWidth: 5,
outLineWidth: 1,
highlightColor: highlightColorValue,
type: 'solid',
labelOption: {

View File

@ -1,5 +1,5 @@
<template>
<div ref="chartRef" :style="{ width: '100%', height: '100%' }"></div>
<div ref="chartRef" class="chart-container"></div>
</template>
<script setup>
@ -31,9 +31,11 @@ const initChart = () => {
}
},
legend: {
type: 'scroll', // 启用滚动图例
selectedMode: 'multiple',
orient: 'vertical',
right: '0%',
top: '1%',
top: 'center',
textStyle: {
color: '#fff'
},
@ -43,7 +45,15 @@ const initChart = () => {
const target = data.find(item => item.name === name)
const percentage = ((target.value / total) * 100).toFixed(0)
return `${name} ${target.value}`
}
},
// 图例翻页配置
pageIconColor: '#fff', // 翻页按钮颜色
pageTextStyle: { color: '#fff' }, // 翻页文字颜色
pageIconSize: 12, // 翻页按钮大小
pageButtonItemGap: 5, // 分页按钮之间的间距
pageButtonGap: 10, // 分页按钮与图例项之间的间距
pageIconInactiveColor: '#555', // 不激活的翻页按钮颜色
pageButtonPosition: 'end' // 翻页按钮的位置
},
series: [{
type: 'pie',
@ -166,4 +176,9 @@ onUnmounted(() => {
</script>
<style scoped></style>
<style scoped>
.chart-container {
width: 100%;
height: 100%;
}
</style>

View File

@ -207,11 +207,14 @@ const onContextmenu = (menu, el) => {
height: 36px;
line-height: 36px;
color: #24b6dd;
// width: 120px;
font-size: 14px;
margin-left: 5px;
margin-right: 28px;
// display: inline-flex;
align-items: center;
// white-space: nowrap;
// overflow: hidden;
// text-overflow: ellipsis;
span {
vertical-align: middle;
@ -299,4 +302,12 @@ const onContextmenu = (menu, el) => {
}
}
}
</style>
::v-deep .tags-view-item span{
text-align: center;
width:100px;
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

View File

@ -409,7 +409,7 @@ export const publicRoutes = [
path: "/CollectCrculate",
name: "CollectCrculate",
// component: () => import("@/views/backOfficeSystem/HumanIntelligence/CollectCrculate/index"),
meta: { title: "上报信息", icon: "article" },
meta: { title: "信息采集", icon: "article" },
// meta: { title: "人力情报信息报送", icon: "article" },
redirect: "/CollectCrculate",
children: [
@ -423,7 +423,24 @@ export const publicRoutes = [
path: "/socialInformationCrculate",
name: "socialInformationCrculate",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/SocialInformationCrculate/index"),
meta: { title: "信息", icon: "article" },
meta: { title: "内部列表", icon: "article" },
},
{
path: "/socialInformationCrculate",
name: "socialInformationCrculate",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/SocialInformationCrculate/index"),
meta: { title: "开源列表", icon: "article" },
},
{
path: "/socialInformationCrculate",
name: "socialInformationCrculate",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/SocialInformationCrculate/index"),
meta: { title: "转合成", icon: "article" },
}, {
path: "/socialInformationCrculate",
name: "socialInformationCrculate",
component: () => import("@/views/backOfficeSystem/HumanIntelligence/SocialInformationCrculate/index"),
meta: { title: "转线索", icon: "article" },
},
]

View File

@ -5,19 +5,19 @@ import { getItem } from '@/utils/storage'
*/
const getChildrenRoutes = (routes) => {
const result = [];
const { deptBizType, deptLevel } = getItem('deptId')[0]
// const { deptBizType, deptLevel } = getItem('deptId')[0]
routes.forEach((route) => {
if (route.children && route.children.length > 0) {
if (deptBizType == '23') {
result.push(...route.children);
} else {
if (route.path == '/HumanIntelligence') {
route.children.splice(0, 1);
result.push(...route.children);
} else {
result.push(...route.children);
}
}
// if (deptBizType == '23') {
result.push(...route.children);
// } else {
// if (route.path == '/HumanIntelligence') {
// route.children.splice(0, 1);
// result.push(...route.children);
// } else {
// result.push(...route.children);
// }
// }
}
});
console.log(result);

View File

@ -14,13 +14,13 @@
</el-icon>
<span style="vertical-align: middle">导出</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="batchMark(ids)" v-if="qxkz.deptLevel == '01'">
<el-button type="primary" :disabled="ids.length === 0" @click="batchMark(ids)" v-if="qxkz.deptLevel == '01'">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle" >批量打标</span>
<span style="vertical-align: middle">批量打标</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="qxkz.deptLevel != '01'">
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="qxkz.deptLevel != '01'">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
@ -56,13 +56,15 @@
<!-- 操作 -->
<template #controls="{ row }">
<!-- 01 提交 02 上报 03 采纳 04 退回 05 打标签v-if="qxkz.deptLevel == '01'" -->
<el-link size="small" type="primary" v-if="row.czzt == '02'&&qxkz.deptLevel == '01'" @click="cnMsg(row)">采纳</el-link>
<el-link size="small" type="primary" v-if="row.czzt == '03'&&qxkz.deptLevel == '01'" @click="opneMsg(row)">打标签</el-link>
<el-link size="small" type="primary" v-if="row.czzt == '02' && qxkz.deptLevel == '01'"
@click="cnMsg(row)">采纳</el-link>
<el-link size="small" type="primary" v-if="row.czzt == '03' && qxkz.deptLevel == '01'"
@click="opneMsg(row)">打标签</el-link>
<el-link size="small" type="primary" @click="rollbackNewspapers(row)"
v-if="row.czzt == '02' && row.qbjb == '00'" >回退</el-link>
<el-link size="small" type="primary" @click="checkProcess(row)">查看流程</el-link>
v-if="row.czzt == '02' && row.qbjb == '00'">回退</el-link>
<el-link size="small" type="primary" @click="checkProcess(row)">查看流程</el-link>
<el-link size="small" type="primary" @click="appearNewspapers(row)"
v-if="row.czzt == '01' || row.czzt == '04' && row.qbjb == '00'&&qxkz.deptLevel != '01'">上报</el-link>
v-if="row.czzt == '01' || row.czzt == '04' && row.qbjb == '00' && qxkz.deptLevel != '01'">上报</el-link>
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
<el-link size="small" type="primary" @click="addEdit('edit', row)">修改</el-link>
<el-link size="small" type="danger" @click="delDictItem(row.id)">删除</el-link>
@ -92,7 +94,7 @@
: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" />
<CheckProcess v-model="checkProcessModel" :dataList="dataList" :dict="{ D_BZ_QBCZZT}"/>
<CheckProcess v-model="checkProcessModel" :dataList="dataList" :dict="{ D_BZ_QBCZZT }" />
</template>
@ -104,21 +106,21 @@ import Pages from "@/components/aboutTable/Pages.vue";
import Search 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 { qbcjSelectQbsbPage, qbcjDeletes, qbcjCzzt, qbcjPlsb } from "@/api/Intelligence.js";
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import MakeTag from '../components/maketag.vue'
import ExportFile from './components/exportFile.vue'
import CheckProcess from '../components/checkProcess.vue'
import CheckProcess from '../components/checkProcess.vue'
import { ElMessageBox } from 'element-plus'
import { getItem } from '@//utils/storage.js'
import {tbYjxxGetZbtj} from '@/api/yj.js'
import { tbYjxxGetZbtj } from '@/api/yj.js'
const { proxy } = getCurrentInstance();
const { D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, 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 } =
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_GS_ZDQT_LB", "D_BZ_CLPP", "D_BZ_CLYS", "D_BZ_CLLX", "D_BZ_XZQHDM", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB"); //获取字典数据
const detailDiloag = ref();
const searchBox = ref(); //搜索框
const ids = ref([])
@ -127,7 +129,7 @@ const chooseData = (val) => {
ids.value = val.map(item => {
return item.id
})
tableList.value=val
tableList.value = val
}
@ -210,7 +212,7 @@ const opneMsg = (item) => {
dataList.value = [item]
}
const cnMsg = (item) => {
proxy.$confirm("确定要采纳", "警告", { type: "warning" }).then(() => {
proxy.$confirm("确定要采纳", "警告", { type: "warning" }).then(() => {
qbcjCzzt({ id: item.id, czzt: '03', qbjb: '00' }).then(res => {
proxy.$message({ type: "success", message: "采纳成功" });
getList();
@ -220,10 +222,10 @@ proxy.$confirm("确定要采纳", "警告", { type: "warning" }).then(() => {
}
// 批量打标
const batchMark = () => {
const listDb= tableList.value.filter(item => item.czzt != '03')
const listDb = tableList.value.filter(item => item.czzt != '03')
if (listDb.length == 0) {
chooseRow.value = true
dataList.value = tableList.value
chooseRow.value = true
dataList.value = tableList.value
} else {
proxy.$message({
message: '还有情报未审批',
@ -235,12 +237,12 @@ const listDb= tableList.value.filter(item => item.czzt != '03')
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(() => { });
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
qbcjPlsb({ ids: ids.value, qbjb: '00' }).then(res => {
proxy.$message({ type: "success", message: "上报成功" });
getList();
})
}).catch(() => { });
} else {
proxy.$message({
message: '请选择正确数据',
@ -256,8 +258,8 @@ const handleSumbit = () => {
const onSearch = (val) => {
const { lrkssj, zxkssj } = val
const promes = {
...pageData.pageConfiger,
...val,
...pageData.pageConfiger,
...val,
lrkssj: lrkssj ? lrkssj[0] : '',
lrjssj: lrkssj ? lrkssj[1] : '',
zxkssj: zxkssj ? zxkssj[0] : '',
@ -330,7 +332,7 @@ const qxkz = reactive({
deptLevel: '',
});
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
const { deptBizType, deptLevel } = getItem('deptId')[0]
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
@ -354,8 +356,8 @@ const exportFileModel = ref(false)
const dologCancel = () => {
exportFileModel.value = true;
}
// 流程
const checkProcessModel=ref()
// 流程
const checkProcessModel = ref()
const checkProcess = (item) => {
checkProcessModel.value = true
dataList.value = item

View File

@ -90,12 +90,8 @@ const pageData = reactive({
},
controlsWidth: 150,
tableColumn: [
// { label: "预警名称", prop: "", showOverflowTooltip: true },
// { label: "预警图片", prop: "yjTp", showOverflowTooltip: true, showSolt: true },
{ label: "报警人", prop: "bjrmc", showOverflowTooltip: true },
{ label: "接警单号", prop: "bjh", showOverflowTooltip: true },
// { label: "车牌号", prop: "yjClcph", showOverflowTooltip: true },
// { label: "身份证号", prop: "yjRysfzh", showOverflowTooltip: true },
{ label: "报警时间", prop: "bjsj", showOverflowTooltip: true },
{ label: "报警地址", prop: "bjdz", showOverflowTooltip: true },
{ label: "类型", prop: "yjlx", showSolt: true },

View File

@ -0,0 +1,88 @@
<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">保存</el-button> -->
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage :formList="formData" v-model="listQuery" ref="elform">
</FormMessage>
</div>
</div>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { tbYjxxGetInfo,yjzxXwyjSelectList } from "@/api/yj.js";
import { IdCard } from '@/utils/validate.js'
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch } from "vue";
const emit = defineEmits(["updateDate"]);
const props = defineProps({
dict: {
type: Object,
default: () => { }
}
});
const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗
const formData = ref([])
watch(() => props.dict, (res) => {
if (res) {
formData.value = [
{ label: "预警人姓名", prop: "xm", type: "input" },
{ label: "身份证号", prop: "sfzh", type: "input" },
{ label: "电话", prop: "dh", type: "input" },
{ label: "行为大类", prop: "xldlmc", type: "input" },
{ label: "行为子类", prop: "xwzlmc", type: "input" },
{ label: "行为次数", prop: "xwcs", type: "input",lx:"number" },
{ label: "标签颜色", prop: "bqys", type: "select", options: props.dict.D_GS_SSYJ },
{ label: "预警时间", prop: "yjsj", type: "input" },
{ label: "行为分值", prop: "xwfz", type: "input",lx:"number" },
{ label: "处置状态", prop: "czzt", type: "select", options: props.dict.D_GSXT_YJXX_CZZT },
{ label: "所属部门", prop: "ssbm", type: "input" },
{ label: "所属县局", prop: "ssxgaj", type: "input" },
{ label: "所属市局", prop: "sssgaj", type: "input" },
{ label: "接警员姓名", prop: "jjyxm", type: "input" },
{ label: "行为描述", prop: "xwms", type: "textarea", width: "100%" },
]
}
}, { deep: true, immediate: true })
const listQuery = ref({}); //表单
const loading = ref(false);
const elform = ref();
const title = ref("详情");
const init = (row) => {
dialogForm.value = true;
yjzxXwyjSelectList(row.id).then(res => {
listQuery.value = {
...res,
nl: IdCard(res.yjRysfzh, 3) || "",
xb: IdCard(res.yjRysfzh, 2) || "",
xsd: res.xsd + '%'
}
})
};
// 关闭
const close = () => {
listQuery.value = {};
loading.value = false;
dialogForm.value = false;
listQuery.value = {}
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep {
.el-form-item__content {
align-items: normal;
}
}
</style>

View File

@ -31,7 +31,7 @@
<el-link type="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01'">签收</el-link>
<el-link type="success" @click="handleQsFk(row, '反馈')" v-else-if="row.czzt == '02'">反馈</el-link>
<el-link type="success" @click="handleQsFk(row, '查看反馈')" v-else>查看反馈</el-link>
<el-link type="primary" @click="delDictItem(row.id)">详情</el-link>
<el-link type="primary" @click="openAddModel(row)">详情</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
@ -48,6 +48,8 @@
<SemdFqzl ref="semdFqzlRef" :itemData="itemData" @handleClose="handleClose" identification="yj"
:tacitly="tacitly" />
</Information>
<!-- 详情 -->
<AddFrom ref="addModelRef" :dict="{D_GSXT_YJXX_CZZT, D_BZ_YJJB,D_GS_SSYJ}"></AddFrom>
</template>
<script setup>
@ -65,6 +67,7 @@ import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
import emitter from "@/utils/eventBus.js";
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
import { reactive, ref, onMounted, getCurrentInstance, computed, watch } from "vue";
import AddFrom from './components/addFrom.vue'
const { proxy } = getCurrentInstance();
const { D_GS_SSYJ ,D_GSXT_YJXX_CZZT} = proxy.$dict("D_GS_SSYJ","D_GSXT_YJXX_CZZT"); //获取字典数据
const searchBox = ref(); //搜索框
@ -249,6 +252,12 @@ const handleQsFk = (val, type) => {
}
const addModelRef = ref(null)
const openAddModel = (row) => {
console.log(row);
addModelRef.value.init(row)
}
// 表格高度计算

View File

@ -0,0 +1,92 @@
<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">保存</el-button> -->
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage :formList="formData" v-model="listQuery" ref="elform">
</FormMessage>
</div>
</div>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { tbYjxxGetInfo,yjzxZhyjSelectList } from "@/api/yj.js";
import { IdCard } from '@/utils/validate.js'
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch } from "vue";
import AddFrom from "../components/addFrom.vue";
const emit = defineEmits(["updateDate"]);
const props = defineProps({
dict: {
type: Object,
default: () => { }
}
});
const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗
const formData = ref([])
watch(() => props.dict, (res) => {
if (res) {
formData.value = [
{ label: "预警人姓名", prop: "xm", type: "input" },
{ label: "身份证号", prop: "sfzh", type: "input" },
{ label: "电话", prop: "dh", type: "input" },
{ label: "组合大类", prop: "sfdlmc", type: "input" },
{ label: "组合小类", prop: "sfzlmc", type: "input" },
{ label: "组合预警次数", prop: "sfcs", type: "input",lx:"number" },
{ label: "标签颜色", prop: "bqys", type: "select", options: props.dict.D_GS_SSYJ },
{ label: "预警时间", prop: "yjsj", type: "input" },
{ label: "预警分值", prop: "sffz", type: "input",lx:"number" },
{ label: "处置状态", prop: "czzt", type: "select", options: props.dict.D_GSXT_YJXX_CZZT },
{ label: "所属部门", prop: "ssbm", type: "input" },
{ label: "所属县局", prop: "ssxgaj", type: "input" },
{ label: "所属市局", prop: "sssgaj", type: "input" },
{ label: "接警员姓名", prop: "jjyxm", type: "input" },
// { label: "预警内容", prop: "yjNr", type: "textarea", width: "100%" },
]
}
}, { deep: true, immediate: true })
const listQuery = ref({}); //表单
const loading = ref(false);
const elform = ref();
const title = ref("详情");
const init = (row) => {
console.log(row);
dialogForm.value = true;
yjzxZhyjSelectList(row.id).then(res => {
listQuery.value = {
...res,
nl: IdCard(res.yjRysfzh, 3) || "",
xb: IdCard(res.yjRysfzh, 2) || "",
xsd: res.xsd + '%'
}
})
};
// 关闭
const close = () => {
listQuery.value = {};
loading.value = false;
dialogForm.value = false;
listQuery.value = {}
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep {
.el-form-item__content {
align-items: normal;
}
}
</style>

View File

@ -31,7 +31,7 @@
<el-link type="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01'">签收</el-link>
<el-link type="success" @click="handleQsFk(row, '反馈')" v-else-if="row.czzt == '02'">反馈</el-link>
<el-link type="success" @click="handleQsFk(row, '查看反馈')" v-else>查看反馈</el-link>
<el-link type="primary" @click="delDictItem(row.id)">详情</el-link>
<el-link type="primary" @click="openAddModel(row)">详情</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
@ -47,6 +47,7 @@
<SemdFqzl ref="semdFqzlRef" :itemData="itemData" @handleClose="handleClose" identification="yj"
:tacitly="tacitly" />
</Information>
<AddFrom ref="addModelRef" :dict="{D_GSXT_YJXX_CZZT, D_BZ_YJJB,D_GS_SSYJ}"/>
</template>
<script setup>
@ -59,6 +60,7 @@ import HolographicArchive from '@/views/home/components/holographicArchive.vue'
import Information from "@/views/home/model/information.vue";
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
import AddFrom from "./components/addFrom.vue";
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import Detail from './components/detail.vue'
@ -224,7 +226,12 @@ const handleQsFk = (val, type) => {
}
}
const addModelRef = ref(null)
const openAddModel = (row) => {
console.log(row);
addModelRef.value.init(row)
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;

View File

@ -0,0 +1,89 @@
<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">保存</el-button> -->
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage :formList="formData" v-model="listQuery" ref="elform">
</FormMessage>
</div>
</div>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { tbYjxxGetInfo,yjzxyjzxSfyjSelectList } from "@/api/yj.js";
import { IdCard } from '@/utils/validate.js'
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch } from "vue";
const emit = defineEmits(["updateDate"]);
const props = defineProps({
dict: {
type: Object,
default: () => { }
}
});
const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗
const formData = ref([])
watch(() => props.dict, (res) => {
if (res) {
formData.value = [
{ label: "预警人姓名", prop: "xm", type: "input" },
{ label: "身份证号", prop: "sfzh", type: "input" },
{ label: "电话", prop: "dh", type: "input" },
{ label: "组合大类", prop: "sfdlmc", type: "input" },
{ label: "组合小类", prop: "sfzlmc", type: "input" },
{ label: "组合预警次数", prop: "sfcs", type: "input",lx:"number" },
{ label: "标签颜色", prop: "bqys", type: "select", options: props.dict.D_GS_SSYJ },
{ label: "预警时间", prop: "yjsj", type: "input" },
{ label: "预警分值", prop: "sffz", type: "input",lx:"number" },
{ label: "处置状态", prop: "czzt", type: "select", options: props.dict.D_GSXT_YJXX_CZZT },
{ label: "所属部门", prop: "ssbm", type: "input" },
{ label: "所属县局", prop: "ssxgaj", type: "input" },
{ label: "所属市局", prop: "sssgaj", type: "input" },
{ label: "接警员姓名", prop: "jjyxm", type: "input" },
// { label: "预警内容", prop: "yjNr", type: "textarea", width: "100%" },
]
}
}, { deep: true, immediate: true })
const listQuery = ref({}); //表单
const loading = ref(false);
const elform = ref();
const title = ref("详情");
const init = (type, row) => {
dialogForm.value = true;
yjzxyjzxSfyjSelectList(row.id).then(res => {
listQuery.value = {
...res,
nl: IdCard(res.yjRysfzh, 3) || "",
xb: IdCard(res.yjRysfzh, 2) || "",
xsd: res.xsd + '%'
}
})
};
// 关闭
const close = () => {
listQuery.value = {};
loading.value = false;
dialogForm.value = false;
listQuery.value = {}
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep {
.el-form-item__content {
align-items: normal;
}
}
</style>

View File

@ -43,7 +43,7 @@
<el-link type="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01'">签收</el-link>
<el-link type="success" @click="handleQsFk(row, '反馈')" v-else-if="row.czzt == '02'">反馈</el-link>
<el-link type="success" @click="handleQsFk(row, '查看反馈')" v-else>查看反馈</el-link>
<el-link type="primary" @click="delDictItem(row.id)">详情</el-link>
<el-link type="primary" @click="openAddFrom(row)">详情</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
@ -59,6 +59,7 @@
<SemdFqzl ref="semdFqzlRef" :itemData="itemData" @handleClose="handleClose" identification="yj"
:tacitly="tacitly" />
</Information>
<AddFrom ref="addModelRef" :dict="{D_GSXT_YJXX_CZZT, D_BZ_YJJB,D_GS_SSYJ}"/>
</template>
<script setup>
@ -69,6 +70,7 @@ import Pages from "@/components/aboutTable/Pages.vue";
import HolographicArchive from '@/views/home/components/holographicArchive.vue'
import Information from "@/views/home/model/information.vue";
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
import AddFrom from "./components/addFrom.vue";
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
@ -79,7 +81,7 @@ import { watch } from "vue";
import emitter from "@/utils/eventBus.js";
const { proxy } = getCurrentInstance();
const searchBox = ref();
const {D_GSXT_YJXX_CZZT} = proxy.$dict("D_GSXT_YJXX_CZZT")
const {D_GSXT_YJXX_CZZT,D_GS_SSYJ} = proxy.$dict("D_GSXT_YJXX_CZZT","D_GS_SSYJ")
// 搜索配置
const searchConfiger = ref([
{ label: "姓名", prop: 'xm', placeholder: "请输入姓名", showType: "input" },
@ -256,6 +258,12 @@ const bqYs = (val) => {
return '#0000ff'
}
}
// 新增
const addModelRef = ref(null)
const openAddFrom = (row) => {
addModelRef.value.init('add', row)
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;

View File

@ -0,0 +1,109 @@
<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">保存</el-button> -->
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="form_cnt">
<FormMessage :formList="formData" v-model="listQuery" ref="elform">
<template #yjTp>
<template v-if="!listQuery.yjTp || listQuery.yjTp.includes('baidu')">
<img src="@/assets/images/car.png" width="80" height="100" v-if="listQuery.yjlx == 2" />
<img src="@/assets/images/default_male.png" width="80" height="100" v-else />
</template>
<el-image v-else style="width: 80px; height:120px" :src="listQuery.yjTp" :preview-src-list="[listQuery.yjTp]"
show-progress>
<template #error>
<div class="image-slot error">
<img src="@/assets/images/car.png" width="80" height="100" v-if="listQuery.yjlx == 2" />
<img src="@/assets/images/default_male.png" width="80" height="100" v-else />
</div>
</template>
</el-image>
</template>
</FormMessage>
</div>
</div>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { tbYjxxGetInfo } from "@/api/yj.js";
import { IdCard } from '@/utils/validate.js'
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, watch } from "vue";
const emit = defineEmits(["updateDate"]);
const props = defineProps({
dict: {
type: Object,
default: () => { }
}
});
const { proxy } = getCurrentInstance();
const dialogForm = ref(false); //弹窗
const formData = ref([])
watch(() => props.dict, (res) => {
if (res) {
formData.value = [
{ label: "预警图片", prop: "yjTp", type: "slot" },
{ label: "预警标题", prop: "yjBt", type: "input" },
{ label: "预警人姓名", prop: "yjRyxm", type: "input" },
{ label: "年龄", prop: "nl", type: "input" },
{ label: "性别", prop: "xb", type: "input" },
{ label: "预警级别", prop: "yjJb", type: "select", options: props.dict.D_BZ_YJJB },
{ label: "相似度", prop: "xsd", type: "input" },
{ label: "预警时间", prop: "yjSj", type: "input" },
{ label: "预警地点", prop: "yjDz", type: "input" },
{ label: "预警次数", prop: "yjCs", type: "input" },
{ label: "处置状态", prop: "czzt", type: "select", options: props.dict.D_GSXT_YJXX_CZZT },
{ label: "布控手机号", prop: "yjRysjh", type: "input" },
{ label: "布控车牌号", prop: "yjClcph", type: "input" },
{ label: "布控身份证", prop: "yjRysfzh", type: "input" },
{ label: "预警标签", prop: "yjbqmc", type: "input" },
{ label: "所属部门", prop: "ssbm", type: "input" },
{ label: "所属县局", prop: "ssxgaj", type: "input" },
{ label: "所属市局", prop: "sssgaj", type: "input" },
{ label: "接警员姓名", prop: "jjyxm", type: "input" },
{ label: "预警内容", prop: "yjNr", type: "textarea", width: "100%" },
]
}
}, { deep: true, immediate: true })
const listQuery = ref({}); //表单
const loading = ref(false);
const elform = ref();
const title = ref("详情");
const init = (type, row) => {
dialogForm.value = true;
tbYjxxGetInfo(row.id).then(res => {
listQuery.value = {
...res,
nl: IdCard(res.yjRysfzh, 3) || "",
xb: IdCard(res.yjRysfzh, 2) || "",
xsd: res.xsd + '%'
}
})
};
// 关闭
const close = () => {
listQuery.value = {};
loading.value = false;
dialogForm.value = false;
listQuery.value = {}
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep {
.el-form-item__content {
align-items: normal;
}
}
</style>

View File

@ -44,7 +44,7 @@
<el-link type="success" @click="handleQsFk(row, '签收')" v-if="row.czzt == '01'">签收</el-link>
<el-link type="success" @click="handleQsFk(row, '反馈')" v-else-if="row.czzt == '02'">反馈</el-link>
<el-link type="success" @click="handleQsFk(row, '查看反馈')" v-else>查看反馈</el-link>
<el-link type="primary" @click="delDictItem(row.id)">详情</el-link>
<el-link type="primary" @click="openAddFrom(row)">详情</el-link>
</template>
<!-- <el-button type="success" @click="showFeedback(item, '签收')" v-if="item.czzt == '01'">签收</el-button>
<el-button type="success" @click="showFeedback(item, '反馈')" v-if="item.czzt == '02'">反馈</el-button>
@ -63,6 +63,7 @@
<SemdFqzl ref="semdFqzlRef" :itemData="itemData" @handleClose="handleClose" identification="yj"
:tacitly="tacitly" />
</Information>
<AddFrom ref="addFrom" />
</template>
<script setup>
@ -75,6 +76,7 @@ import Information from "@/views/home/model/information.vue";
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
import emitter from "@/utils/eventBus.js";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
@ -205,7 +207,9 @@ const submit = () => {
const closeFszl = () => {
semdFqzlRef.value.close()
}
function close() {
const addFrom = ref()
const openAddFrom = (row) => {
emitter.emit('openAddFrom',row)
}
// 表格高度计算
const tabHeightFn = () => {

View File

@ -86,24 +86,25 @@
</div>
</template>
</el-dialog>
<AddFrom ref="addFromRef" :dict="{D_GSXT_YJXX_CZZT, D_BZ_YJJB}"/>
</template>
<script setup>
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import Search from "@/components/aboutTable/Search.vue";
import * as MOSTY from "@/components/MyComponents/index";
import { IdCard } from '@/utils/validate.js'
import { tbGsxtZdrySelectList } from "@/api/zdr.js"
import { tbYjxxQueryYjxx } from "@/api/yj.js";
import LocalWarning from "./components/localWarning.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import AddFrom from './components/addFrom.vue';
import FileSaver from "file-saver";
import emitter from "@/utils/eventBus.js";
import * as XLSX from "xlsx";
const { proxy } = getCurrentInstance();
const { D_BZ_YJLX, D_GSXT_YJXX_CZZT, D_BZ_YJJB } = proxy.$dict("D_BZ_YJLX", "D_GSXT_YJXX_CZZT","D_BZ_YJJB")
const searchBox = ref(); //搜索框
const form = ref({});
const shortcuts = [
{
text: '近一周',
@ -133,7 +134,6 @@ const shortcuts = [
},
},
]
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
@ -168,8 +168,12 @@ const pageData = reactive({
});
const showDc = ref(false)
const activeName = ref('local')
const addFromRef = ref(null)
onMounted(() => {
tabHeightFn();
emitter.on('openAddFrom', (val) => {
addFromRef.value.init('add', val)
})
});
const listQuery = ref({})
const opentions = ref([])

View File

@ -47,7 +47,8 @@
item.yjnr }}</div>
</div>
<div class="mt4 two_text_detail" v-if="buttonBox">
<el-button type="primary" @click="pushAssess(item)">全息档案</el-button>
<el-button type="primary" @click="pushAssess(item)">全息档案</el-button>
<el-button type="primary" @click="pushWarning(item)">预警指派</el-button>
<el-button color="#ef7762" @click="showDetail(item)" style="color: #fff;">转合成</el-button>
<!-- <el-button type="warning">转基管</el-button> -->
<el-button type="danger">转会商</el-button>
@ -59,13 +60,15 @@
<!-- props.item.czzt == '03'" -->
</div>
<HolographicArchive v-model="assessShow" :dataList="dataList" />
<WarningAssignment v-model="warningShow" :dataList="dataList"/>
</template>
<script setup>
import { IdCard } from '@/utils/validate.js'
import { reactive, ref, getCurrentInstance } from "vue";
import { reactive, ref, getCurrentInstance, watch } from "vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import HolographicArchive from './holographicArchive.vue'
import WarningAssignment from './warningAssignment.vue'
const { proxy } = getCurrentInstance();
const props = defineProps({
@ -80,15 +83,18 @@ const props = defineProps({
default: false
}
});
const emit = defineEmits(["plotThetrajectory", "showDetail", 'showFeedback']);
watch(() => props.item, (newVal, oldVal) => {
emit('fkLxOptions', newVal);
},{deep:true,immediate:true})
const emit = defineEmits(["plotThetrajectory", "showDetail", 'showFeedback','fkLxOptions']);
const changeBG = (str) => {
switch (str) {
case "10":
case "01":
return "red";
case "20":
case "02":
return "orange";
case "30":
case "03":
return "#b5b522";
default:
return "blue";
@ -103,6 +109,16 @@ const showFeedback = (val, type) => {
switch (type) {
case '签收':
proxy.$confirm("是否确定要签收", "警告", { type: "warning" }).then(() => {
// switch (val.czzt) {
// case '01':
// val.czzt = '02'
// break;
// case '02':
// val.czzt = '03'
// break;
// default:
// break;
// }
qcckPost({ id: val.id }, "/mosty-gsxt/tbYjxx/yjqs").then(() => {
val.czzt = '02'
proxy.$message({ type: "success", message: "签收成功" });
@ -122,12 +138,19 @@ const showFeedback = (val, type) => {
const showDetail = (item) => {
emit('showDetail', item);
}
// 全息档案
const assessShow = ref(false)
const dataList = ref()
const pushAssess = (val) => {
assessShow.value = true;
dataList.value = val;
}
// 预警指派
const warningShow = ref(false)
const pushWarning = (val) => {
warningShow.value = true;
dataList.value = val;
}
</script>
<style lang="scss" scoped>

View File

@ -1,157 +1,158 @@
<!--全息档案展示组件 -->
<template>
<el-dialog :draggable="true" v-model="modelValue" :title="title" :width="width" @close="close" append-to-body>
<el-dialog v-model="modelValue" :title="title" :width="width" @close="close" top="5vh" append-to-body>
<div class="archive-container">
<!-- 基本信息卡片 -->
<div class="basic-info-card">
<div class="info-header">
<!-- 头像区域 -->
<div class="avatar-section">
<el-image class="main-avatar" :src="personData.rltp || personData.qsztp" fit="cover"
:preview-src-list="[personData.rltp , personData.qsztp]" />
</div>
<!-- 基本信息 -->
<div class="basic-info">
<!-- 姓名字段单独一行 -->
<div class="info-row">
<div class="info-item">
<span class="info-label">姓名</span>
<span class="info-value">{{ personData.xm || '未记录' }}</span>
<div style="display: flex;justify-content: space-between;">
<div class="basic-info-card">
<div class="info-header">
<!-- 头像区域 -->
<div class="avatar-section">
<el-image class="main-avatar" :src="personData.rltp || personData.qsztp" fit="cover"
:preview-src-list="[personData.rltp, personData.qsztp]" />
</div>
<!-- 基本信息 -->
<div class="basic-info">
<!-- 姓名字段单独一行 -->
<div class="info-row">
<div class="info-item">
<span class="info-label">姓名</span>
<span class="info-value">{{ personData.xm || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">身份号</span>
<span class="info-value">{{ personData.sfzhm || '未记录' }}</span>
</div>
</div>
<div class="info-item">
<span class="info-label">身份号</span>
<span class="info-value">{{ personData.sfzhm || '未记录' }}</span>
<!-- 基本信息 - 两个字段一行 -->
<div class="info-row">
<div class="info-item">
<span class="info-label">出生日期</span>
<span class="info-value">{{ personData.csrq || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">性别</span>
<span class="info-value">{{ personData.xb || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">民族</span>
<span class="info-value">{{ personData.mz || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">婚姻状况</span>
<span class="info-value">{{ personData.hyzq || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">联系方式</span>
<span class="info-value">{{ personData.lxfs || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">户主号码</span>
<span class="info-value">{{ personData.hzhm || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">文化程度</span>
<span class="info-value">{{ personData.whcd || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">毕业情况</span>
<span class="info-value">{{ personData.byqq || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">身高</span>
<span class="info-value">{{ personData.sg || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item full-width">
<span class="info-label">人员标签</span>
<span class="info-value">{{ personData.rybq || '未记录' }}</span>
</div>
</div>
</div>
</div>
<!-- 基本信息 - 两个字段一行 -->
<!-- 详细信息 -->
<div class="detail-info">
<!-- 详细信息 - 两个字段一行 -->
<div class="info-row">
<div class="info-item">
<span class="info-label">出生日期</span>
<span class="info-value">{{ personData.csrq || '未记录' }}</span>
<span class="info-label">人员国籍</span>
<span class="info-value">{{ personData.rygj || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">性别</span>
<span class="info-value">{{ personData.xb || '未记录' }}</span>
<span class="info-label">人员地区</span>
<span class="info-value">{{ personData.rydq || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">户籍城市</span>
<span class="info-value">{{ personData.hjcs || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">户籍籍贯</span>
<span class="info-value">{{ personData.hjjg || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">工作单位</span>
<span class="info-value">{{ personData.gzdw || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">职业信息</span>
<span class="info-value">{{ personData.zyxx || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">民族</span>
<span class="info-value">{{ personData.mz || '未记录' }}</span>
<span class="info-label">入境时间</span>
<span class="info-value">{{ personData.rjsj || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">婚姻状况</span>
<span class="info-value">{{ personData.hyzq || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">联系方式</span>
<span class="info-value">{{ personData.lxfs || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">户主号码</span>
<span class="info-value">{{ personData.hzhm || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">文化程度</span>
<span class="info-value">{{ personData.whcd || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">毕业情况</span>
<span class="info-value">{{ personData.byqq || '未记录' }}</span>
<span class="info-label">入境事由</span>
<span class="info-value">{{ personData.rjsy || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">身高</span>
<span class="info-value">{{ personData.sg || '未记录' }}</span>
<span class="info-label">证件类型</span>
<span class="info-value">{{ personData.qzlx || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">证件号码</span>
<span class="info-value">{{ personData.qzhm || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item full-width">
<span class="info-label">人员标签</span>
<span class="info-value">{{ personData.rybq || '未记录' }}</span>
<div class="info-item">
<span class="info-label">证件校验</span>
<span class="info-value">{{ personData.zjxy || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">境外人员类别</span>
<span class="info-value">{{ personData.jwrylb || '未记录' }}</span>
</div>
</div>
</div>
</div>
<!-- 详细信息 -->
<div class="detail-info">
<!-- 详细信息 - 两个字段一行 -->
<div class="info-row">
<div class="info-item">
<span class="info-label">人员国籍</span>
<span class="info-value">{{ personData.rygj || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">人员地区</span>
<span class="info-value">{{ personData.rydq || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">户籍城市</span>
<span class="info-value">{{ personData.hjcs || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">户籍籍贯</span>
<span class="info-value">{{ personData.hjjg || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">工作单位</span>
<span class="info-value">{{ personData.gzdw || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">职业信息</span>
<span class="info-value">{{ personData.zyxx || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">入境时间</span>
<span class="info-value">{{ personData.rjsj || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">入境事由</span>
<span class="info-value">{{ personData.rjsy || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">证件类型</span>
<span class="info-value">{{ personData.qzlx || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">证件号码</span>
<span class="info-value">{{ personData.qzhm || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">证件校验</span>
<span class="info-value">{{ personData.zjxy || '未记录' }}</span>
</div>
<div class="info-item">
<span class="info-label">境外人员类别</span>
<span class="info-value">{{ personData.jwrylb || '未记录' }}</span>
</div>
</div>
<!-- <div class="info-row">
<!-- <div class="info-row">
<div class="info-item">
<span class="info-label">毕业情况</span>
<span class="info-value">{{ personData.byqq || '未记录' }}</span>
@ -162,14 +163,14 @@
</div>
</div> -->
<!-- <div class="info-row">
<!-- <div class="info-row">
<div class="info-item">
<span class="info-label">户主号码</span>
<span class="info-value">{{ personData.hzhm || '未记录' }}</span>
</div>
</div> -->
<!-- <div class="info-row">
<!-- <div class="info-row">
<div class="info-item">
<span class="info-label">起始图片</span>
@ -177,18 +178,44 @@
</div>
</div> -->
<!-- 户籍和居住地放在最后独占一行 -->
<div class="info-row">
<div class="info-item full-width">
<span class="info-label">户籍所在地</span>
<span class="info-value">{{ personData.hjdz || '未记录' }}</span>
<!-- 户籍和居住地放在最后独占一行 -->
<div class="info-row">
<div class="info-item full-width">
<span class="info-label">户籍所在地</span>
<span class="info-value">{{ personData.hjdz || '未记录' }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item full-width">
<span class="info-label">居住地</span>
<span class="info-value">{{ personData.jzdz || '未记录' }}</span>
</div>
</div>
</div>
<div class="info-row">
<div class="info-item full-width">
<span class="info-label">居住地</span>
<span class="info-value">{{ personData.jzdz || '未记录' }}</span>
</div>
<!-- 右侧表单区域 -->
<div class="form-card" style="width: 50%;margin-left: 20px;">
<div class="form-header">
<div>
<span class="form-title">信息编辑</span>
<span class="form-title" @click="dialogShow = true"><el-icon>
<Plus />
</el-icon></span>
</div>
</div>
<div v-if="fromData.length > 0" class="info-items-container">
<div class="info-item-wrapper" v-for="(item, index) in fromData" :key="index">
<div class="info-item-title">{{ item.bt }}</div>
<div class="info-item-content">
<el-input v-model="item.nr" placeholder="请输入内容" clearable />
<el-icon class="undete-icon" @click="updateItem(item)">
<EditPen />
</el-icon>
<el-icon class="delete-icon" @click="deleteItem(item.id)">
<Delete />
</el-icon>
</div>
</div>
</div>
</div>
@ -199,11 +226,32 @@
<el-button @click="close">关闭</el-button>
</div>
</template>
<el-dialog v-model="dialogShow" title="信息编辑" width="30%" @close="dialogShow = false">
<el-form ref="formRef" :model="listQuery" :rules="rules" label-width="100px">
<el-form-item label="标题" prop="bt">
<el-input v-model="listQuery.bt" placeholder="请输入标题" clearable />
</el-form-item>
<el-form-item label="内容" prop="nr">
<el-input v-model="listQuery.nr" placeholder="请输入内容" clearable />
</el-form-item>
<el-form-item>
<div class="dialog-footer">
<el-button type="primary" @click="closeAdd(formRef)">取消 </el-button>
<el-button @click="submit(formRef)">确定</el-button>
</div>
</el-form-item>
</el-form>
</el-dialog>
</el-dialog>
</template>
<script setup>
import { ref, defineProps, defineEmits, reactive, watch } from 'vue';
import {ryxxJbxxSave} from '@/api/qxda.js'
import { ref, defineProps, defineEmits, reactive, watch, getCurrentInstance } from 'vue';
import { ElMessage } from 'element-plus';
import { ryxxJbxxSave, yjxxDawsAddEntity, yjxxDawsGetPageList, yjxxDawsDeleteEntity, yjxxDawsUpdateEntity } from '@/api/qxda.js'
const { proxy } = getCurrentInstance()
const props = defineProps({
modelValue: {
type: Boolean,
@ -215,7 +263,7 @@ const props = defineProps({
},
width: {
type: String,
default: '50%'
default: '80%'
},
url: {
type: String,
@ -226,38 +274,121 @@ const props = defineProps({
default: () => ({})
}
});
const formRef = ref()
watch(() => props.modelValue, (newVal, oldVal) => {
if (newVal) {
getryxxJbxxSave()
getyjxxDawsGetPageList()
}
})
// 个人信息数据对象 - 使用用户提供的数据
const personData = ref({ });
const personData = ref({});
const rules = reactive({
bt: [{ required: true, message: '请输入标题', trigger: 'blur' }],
nr: [{ required: true, message: '请输入内容', trigger: 'blur' }],
})
// 定义事件
const emit = defineEmits(['update:modelValue']);
const getryxxJbxxSave = () => {
const params = { sfzhm: props.dataList.rysfzh || props.dataList.yjRysfzh||props.dataList.sfzh };
ryxxJbxxSave(params).then((res) => {
personData.value = res[0]
ryxxJbxxSave({
sfzhm: props.dataList.rysfzh // props.dataList.rysfzh
}).then((res) => {
personData.value = res[0]
});
}
const listQuery = ref({})
const dialogShow = ref(false)
// 提交字段
const submit = (formEl) => {
if (!formEl) return
formEl.validate((valid, fields) => {
if (valid) {
const promes = {
yjid: props.dataList.id,
...listQuery.value
}
if (promes.id) {
yjxxDawsUpdateEntity(promes).then((res) => {
ElMessage({
message: '更新成功',
type: 'success'
})
dialogShow.value = false
getyjxxDawsGetPageList()
formRef.value.resetFields()
})
} else {
yjxxDawsAddEntity(promes).then((res) => {
ElMessage({
message: '添加成功',
type: 'success'
})
dialogShow.value = false
getyjxxDawsGetPageList()
formRef.value.resetFields()
})
}
} else {
console.log('error submit!', fields)
}
})
}
const fromData = ref()
const getyjxxDawsGetPageList = () => {
yjxxDawsGetPageList({ yjid: props.dataList.id }).then((res) => {
fromData.value = res ? res : []
})
}
// 删除
const deleteItem = (id) => {
proxy.$confirm('确认删除吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
yjxxDawsDeleteEntity({ ids: [id] }).then((res) => {
ElMessage({
message: '删除成功',
type: 'success'
})
getyjxxDawsGetPageList()
})
})
}
const closeAdd = (formEl) => {
console.log(formEl);
formEl.resetFields()
dialogShow.value = false
}
// 修改
const updateItem = (item) => {
listQuery.value = { ...item }
dialogShow.value = true
}
// 关闭对话框
const close = () => {
emit('update:modelValue', false);
};
</script>
<style scoped>
/* 容器样式 */
.archive-container {
padding: 15px;
height: 50vh;
height: 70vh;
overflow: auto;
}
/* 基本信息卡片 */
.basic-info-card {
flex: 1;
background-color: #f0f9ff;
border: 1px solid #91d5ff;
border-radius: 8px;
@ -375,6 +506,286 @@ const close = () => {
gap: 12px;
}
/* 表单卡片样式 */
.form-card {
background-color: #f0f9ff;
border: 1px solid #91d5ff;
border-radius: 8px;
padding: 25px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
height: 100%;
}
/* 表单头部 */
.form-header {
border-bottom: 1px solid #d6eaff;
padding-bottom: 15px;
margin-bottom: 25px;
}
/* 表单标题容器 */
.form-header div {
display: flex;
align-items: center;
gap: 12px;
justify-content: space-between;
}
/* 表单标题 */
.form-title {
color: #0060c8;
font-size: 18px;
font-weight: bold;
text-shadow: 0 1px 3px rgba(0, 96, 200, 0.3);
letter-spacing: 0.5px;
}
/* 表单标题图标 */
.form-title .el-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 50%;
background: linear-gradient(135deg, #409EFF, #0060c8);
color: white;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(0, 96, 200, 0.3);
}
/* 表单标题图标悬停效果 */
.form-title .el-icon:hover {
transform: scale(1.1);
box-shadow: 0 4px 12px rgba(0, 96, 200, 0.4);
background: linear-gradient(135deg, #66b1ff, #409EFF);
}
/* 档案表单 */
.archive-form {
flex: 1;
display: flex;
flex-direction: column;
gap: 18px;
}
/* 表单元素样式 */
:deep(.el-form-item) {
margin-bottom: 20px;
padding: 12px;
background-color: #fff;
border-radius: 8px;
border: 1px solid #e6f7ff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
transition: all 0.3s ease;
}
:deep(.el-form-item:hover) {
border-color: #91d5ff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
:deep(.el-form-item__label) {
color: #0060c8;
font-weight: bold;
font-size: 14px;
min-width: 80px;
}
/* 表单输入框容器 */
.el-form-item div {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
}
/* 输入框样式 */
:deep(.el-input) {
flex: 1;
}
:deep(.el-input__wrapper),
:deep(.el-select__wrapper) {
border-radius: 4px;
border: 1px solid #91d5ff;
background-color: #fff;
box-shadow: none;
transition: all 0.3s ease;
}
/* 编辑和删除图标样式 */
.el-form-item .el-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 16px;
}
/* 编辑图标样式 */
.el-form-item .el-icon:first-of-type {
color: #67c23a;
background-color: #f0f9eb;
border: 1px solid #e1f3d8;
}
.el-form-item .el-icon:first-of-type:hover {
color: #fff;
background-color: #67c23a;
border-color: #67c23a;
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(103, 194, 58, 0.3);
}
/* 删除图标样式 */
.el-form-item .el-icon:last-of-type {
color: #f56c6c;
background-color: #fef0f0;
border: 1px solid #fbc4c4;
}
.el-form-item .el-icon:last-of-type:hover {
color: #fff;
background-color: #f56c6c;
border-color: #f56c6c;
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(245, 108, 108, 0.3);
}
:deep(.el-input__wrapper:focus-within),
:deep(.el-select__wrapper:focus-within) {
border-color: #409EFF;
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}
:deep(.el-button--primary) {
background-color: #409EFF;
border-color: #409EFF;
border-radius: 4px;
padding: 8px 20px;
font-size: 14px;
}
:deep(.el-button--primary:hover) {
background-color: #66b1ff;
border-color: #66b1ff;
}
:deep(.el-button) {
border-radius: 4px;
padding: 8px 20px;
font-size: 14px;
}
/* 信息项容器 */
.info-items-container {
display: flex;
flex-direction: column;
gap: 16px;
/* align-items: center; */
}
/* 单个信息项包装器 */
.info-item-wrapper {
background-color: #fff;
border-radius: 8px;
border: 1px solid #e6f7ff;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
transition: all 0.3s ease;
display: flex;
align-items: center;
}
/* 信息项悬停效果 */
.info-item-wrapper:hover {
border-color: #91d5ff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
/* 信息项标题 */
.info-item-title {
color: #0060c8;
font-weight: bold;
font-size: 14px;
/* margin-bottom: 12px;
padding-bottom: 8px; */
min-width: 80px;
max-width: 200px;
}
/* 信息项内容容器 */
.info-item-content {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
}
/* 信息项输入框样式 */
.info-item-content :deep(.el-input) {
flex: 1;
}
/* 删除图标样式 */
.info-item-content .delete-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 16px;
color: #f56c6c;
background-color: #fef0f0;
border: 1px solid #fbc4c4;
}
/* 删除图标悬停效果 */
.info-item-content .delete-icon:hover {
color: #fff;
background-color: #f56c6c;
border-color: #f56c6c;
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(245, 108, 108, 0.3);
}
.info-item-content .undete-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 16px;
color: #6cf56e;
background-color: #f2fef0;
border: 1px solid #e1f3d8;
}
/* 删除图标悬停效果 */
.info-item-content .undete-icon:hover {
color: #fff;
background-color: #6cf56e;
border-color: #6cf56e;
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(108, 245, 110, 0.3);
}
/* 响应式设计 */
@media (max-width: 768px) {
.info-header {

View File

@ -0,0 +1,85 @@
<!--预警指派展示组件 -->
<template>
<el-dialog :draggable="true" v-model="modelValue" :title="title" :width="width" @close="close" append-to-body>
<div class="archive-container">
<FormMessage :formList="formData" v-model="listQuery" ref="elform" :rules="rules" :labelWidth="90">
</FormMessage>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submit">确定</el-button>
<el-button @click="close">关闭</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, defineProps, defineEmits, reactive, watch, getCurrentInstance } from 'vue';
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { tbYjxxYjzp } from '@/api/yj'
const { proxy } = getCurrentInstance();
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
title: {
type: String,
default: '预警指派'
},
width: {
type: String,
default: '50%'
},
url: {
type: String,
default: ''
},
dataList: {
type: Object,
default: () => ({})
}
});
const listQuery = ref()
const formData = ref([
{ label: "指派部门", prop: "zpbmdm", depMc: 'zpbm', type: "department", width: '45%' },
{ label: "指派原因", prop: "zpyy", type: "textarea", width: '80%' },
])
const rules = reactive({
zpbmdm: [{ required: true, message: "请选择指派部门", trigger: "blur" }],
zpyy: [{ required: true, message: "请输入指派原因", trigger: "change" }],
});
watch(() => props.modelValue, (newVal, oldVal) => {
if (newVal) {
}
})
const elform = ref(null)
const submit = async () => {
elform.value.submit(() => {
const params = { ...listQuery.value, yjid: props.dataList.id };
tbYjxxYjzp(params).then((res) => {
proxy.$message({ type: "success", message: "成功" });
close();
}).catch(() => {
proxy.$message({ type: "error", message: "失败" });
});
});
}
// 定义事件
const emit = defineEmits(['update:modelValue']);
const close = () => {
elform.value.reset()
emit('update:modelValue', false);
};
</script>
<style scoped>
/* 容器样式 */
.archive-container {
padding: 15px;
height: 50vh;
overflow: auto;
}
</style>

View File

@ -3,15 +3,32 @@
<ul class="warningList" ref="gjyjList">
<li v-for="item in props.data" :key="item">
<deployControlItem :item="item" :buttonBox="true" @plotThetrajectory="plotThetrajectory"
@showFeedback="showFeedback" @showDetail="showDetail"/>
@showFeedback="showFeedback" @showDetail="showDetail" @fkLxOptions="fkLxOptions" />
</li>
<MOSTY.Empty :show="props.data.length <= 0" :imgSize="150"></MOSTY.Empty>
</ul>
<div style="position:relative;width: 100%;" :style="{ height: `calc(100vh - ${handleHs}px)` }">
<GdMap v-if="showMap" :mapKey="'home_yj_map'" :mapid="'homeYjMap'" />
<!-- 地图区域默认收起点击展开 -->
<div class="map-area-container">
<div v-if="!showMap" class="map-toggle-btn" @click="toggleMap">
<el-icon>
<Plus />
</el-icon>
点击展开地图
</div>
<div v-else class="map-content-container">
<!-- <div class="map-toggle-btn" @click="toggleMap">
<el-icon>
<ArrowUpBold />
</el-icon>
点击收起地图
</div> -->
<GdMap :mapKey="'home_yj_map'" :mapid="'homeYjMap'" />
</div>
</div>
</DialogDragger>
<FkDialog @change="close"/>
<FkDialog @change="close" :lx="fkLx" />
<Information v-model="showDialog" title="发送指令" @submit='submit' @close='closeFszl'>
<SemdFqzl ref="semdFqzlRef" :itemData="itemData" @handleClose="handleClose" identification="yj"
:tacitly="tacitly" />
@ -25,12 +42,14 @@ import DialogDragger from "@/views/home/layout/dialogDragger.vue";
import deployControlItem from "@/views/home/components/deployControlItem.vue";
import Information from "@/views/home/model/information.vue";
import SemdFqzl from '@/components/instructionHasBeen/sendFqzl.vue'
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
import FkDialog from "@/views/backOfficeSystem/fourColorManage/warningControl/centerHome/components/fkDialog.vue";
import { tbYjxxGsgj } from '@/api/yj'
import { ref, defineProps, onMounted, watch, getCurrentInstance } from "vue";
import { ArrowUpBold, ArrowDownBold } from '@element-plus/icons-vue';
import emitter from "@/utils/eventBus.js";
const gjyjList = ref(null); //预警列表数据
const { proxy } = getCurrentInstance();
const fkLx = ref('01')
//参数传递
const props = defineProps({
//某条预警详情
@ -48,63 +67,75 @@ const props = defineProps({
function close() {
emitter.emit('deletePointArea', 'home_yj_map');
emitter.emit("showHomeYJ", false);
emitter.emit("closeYp")
emitter.emit("closeYp")
}
const showMap = ref(false)
onMounted(() => {
setTimeout(() => {
showMap.value = true
// 初始化地图数据的函数
const initMapData = () => {
// 只删除一次home_yj_map区域的点避免影响其他地图
emitter.emit('deletePointArea', 'home_yj_map');
// 收集所有有效坐标的数据点
const validPoints = [];
for (let i = 0; i < props.data.length; i++) {
const item = props.data[i];
// 修复重复的坐标判断条件
if (!item.jd || !item.wd) {
// 使用警告而不是return避免中断循环
console.warn("该预警没有坐标:", item);
continue;
}
validPoints.push(item);
}
// 如果有有效点,显示第一条并添加所有点
if (validPoints.length > 0) {
// 只显示第一条数据的详情
emitter.emit('showHomeYJ', [validPoints[0]]);
// 为每个有效点添加标记
validPoints.forEach((item, index) => {
let icon = require('@/assets/point/yj.png');
if (item.yjjb == '20') icon = require('@/assets/point/yj1.png');
if (item.yjjb == '30') icon = require('@/assets/point/yj2.png');
if (item.yjjb == '40') icon = require('@/assets/point/yj3.png');
// 为每个点添加唯一标识,避免与其他地图冲突
emitter.emit('addPointArea', {
flag: `home_yj_map_${index}`,
baseFlag: 'home_yj_map',
icon,
coords: [item]
});
});
// 只设置一次地图中心(使用第一个有效点)
emitter.emit('setMapCenter', {
location: [validPoints[0].jd, validPoints[0].wd],
zoomLevel: 10,
flag: 'home_yj_map' // 添加标识,确保只影响当前地图
});
}
}
// 切换地图显示/隐藏
const toggleMap = () => {
showMap.value = !showMap.value;
// 如果是展开地图,延迟初始化地图数据
if (showMap.value) {
setTimeout(() => {
// 只删除一次home_yj_map区域的点避免影响其他地图
emitter.emit('deletePointArea', 'home_yj_map');
// 收集所有有效坐标的数据点
const validPoints = [];
for (let i = 0; i < props.data.length; i++) {
const item = props.data[i];
// 修复重复的坐标判断条件
if (!item.jd || !item.wd) {
// 使用警告而不是return避免中断循环
console.warn("该预警没有坐标:", item);
continue;
}
validPoints.push(item);
}
// 如果有有效点,显示第一条并添加所有点
if (validPoints.length > 0) {
// 只显示第一条数据的详情
emitter.emit('showHomeYJ', [validPoints[0]]);
// 为每个有效点添加标记
validPoints.forEach((item, index) => {
let icon = require('@/assets/point/yj.png');
if (item.yjjb == '20') icon = require('@/assets/point/yj1.png');
if (item.yjjb == '30') icon = require('@/assets/point/yj2.png');
if (item.yjjb == '40') icon = require('@/assets/point/yj3.png');
// 为每个点添加唯一标识,避免与其他地图冲突
emitter.emit('addPointArea', {
flag: `home_yj_map_${index}`,
baseFlag: 'home_yj_map',
icon,
coords: [item]
});
});
// 只设置一次地图中心(使用第一个有效点)
emitter.emit('setMapCenter', {
location: [validPoints[0].jd, validPoints[0].wd],
zoomLevel: 10,
flag: 'home_yj_map' // 添加标识,确保只影响当前地图
});
}
initMapData();
}, 500);
}, 200);
}
}
onMounted(() => {
// 组件挂载时不自动展开地图,等待用户点击
})
const handleHs = ref(0)
watch(() => gjyjList.value, (val) => {
handleHs.value = val.clientHeight + 198 + 150 + 20
handleHs.value = 500
}, { deep: true })
// 轨迹上图
@ -119,76 +150,76 @@ const plotThetrajectory = (val) => {
let coords = res[0].list.map(item => {
return [item.jd, item.wd]
})
// const coords = [
// [
// 94.3695802486277983689433312974870204925537109375,
// 29.659805088901098457654370577074587345123291015625
// ],
// [
// 94.369054723455093380835023708641529083251953125,
// 29.66032233866609857386720250360667705535888671875
// ],
// [
// 94.3684916577901020673380116932094097137451171875,
// 29.660979382630298317735650925897061824798583984375
// ],
// [
// 94.3683415069466065006054122932255268096923828125,
// 29.660755708570601285600787377916276454925537109375
// ],
// [
// 94.3675662718153063224235665984451770782470703125,
// 29.659987675165101705943015986122190952301025390625
// ],
// [
// 94.366890606904092919648974202573299407958984375,
// 29.659353928438999759009675472043454647064208984375
// ],
// [
// 94.3656729217579055557507672347128391265869140625,
// 29.6582345740253998656044132076203823089599609375
// ],
// [
// 94.3646650204280064144768402911722660064697265625,
// 29.657336173164399184543071896769106388092041015625
// ],
// [
// 94.364147680070203705327003262937068939208984375,
// 29.6567231392728984928908175788819789886474609375
// ],
// [
// 94.3636436022359958997185458429157733917236328125,
// 29.65662527779360146951148635707795619964599609375
// ],
// [
// 94.362367320062702447103220038115978240966796875,
// 29.6567138191363000032652053050696849822998046875
// ],
// [
// 94.3614396063849056872641085647046566009521484375,
// 29.656713819753800720491199172101914882659912109375
// ],
// [
// 94.3603242001151016893345513381063938140869140625,
// 29.65673712009380125209645484574139118194580078125
// ],
// [
// 94.358962121621999585840967483818531036376953125,
// 29.65674177535930056137658539228141307830810546875
// ],
// [
// 94.3576684689077040957272402010858058929443359375,
// 29.65681167375640114869383978657424449920654296875
// ],
// [
// 94.3564404495050013110812869854271411895751953125,
// 29.65685827438640131958891288377344608306884765625
// ],
// [
// 94.3547512464013067301493720151484012603759765625,
// 29.656946809372101370172458700835704803466796875
// ]
// ]
// const coords = [
// [
// 94.3695802486277983689433312974870204925537109375,
// 29.659805088901098457654370577074587345123291015625
// ],
// [
// 94.369054723455093380835023708641529083251953125,
// 29.66032233866609857386720250360667705535888671875
// ],
// [
// 94.3684916577901020673380116932094097137451171875,
// 29.660979382630298317735650925897061824798583984375
// ],
// [
// 94.3683415069466065006054122932255268096923828125,
// 29.660755708570601285600787377916276454925537109375
// ],
// [
// 94.3675662718153063224235665984451770782470703125,
// 29.659987675165101705943015986122190952301025390625
// ],
// [
// 94.366890606904092919648974202573299407958984375,
// 29.659353928438999759009675472043454647064208984375
// ],
// [
// 94.3656729217579055557507672347128391265869140625,
// 29.6582345740253998656044132076203823089599609375
// ],
// [
// 94.3646650204280064144768402911722660064697265625,
// 29.657336173164399184543071896769106388092041015625
// ],
// [
// 94.364147680070203705327003262937068939208984375,
// 29.6567231392728984928908175788819789886474609375
// ],
// [
// 94.3636436022359958997185458429157733917236328125,
// 29.65662527779360146951148635707795619964599609375
// ],
// [
// 94.362367320062702447103220038115978240966796875,
// 29.6567138191363000032652053050696849822998046875
// ],
// [
// 94.3614396063849056872641085647046566009521484375,
// 29.656713819753800720491199172101914882659912109375
// ],
// [
// 94.3603242001151016893345513381063938140869140625,
// 29.65673712009380125209645484574139118194580078125
// ],
// [
// 94.358962121621999585840967483818531036376953125,
// 29.65674177535930056137658539228141307830810546875
// ],
// [
// 94.3576684689077040957272402010858058929443359375,
// 29.65681167375640114869383978657424449920654296875
// ],
// [
// 94.3564404495050013110812869854271411895751953125,
// 29.65685827438640131958891288377344608306884765625
// ],
// [
// 94.3547512464013067301493720151484012603759765625,
// 29.656946809372101370172458700835704803466796875
// ]
// ]
emitter.emit('drawLineAnimation', {
type: "solid",
coords: coords,
@ -202,7 +233,11 @@ const plotThetrajectory = (val) => {
}
// 查看反馈
const showFeedback = (val) => {
emitter.emit("openFkDialog",val )
emitter.emit("openFkDialog", val)
}
const fkLxOptions = (val) => {
fkLx.value = val.yjlx
}
// 发送指令
const showDialog = ref(false)
@ -258,4 +293,35 @@ const closeFszl = () => {
::v-deep .el-loading-mask {
background-color: transparent !important;
}
/* 地图切换按钮样式 */
.map-toggle-btn {
color: #fff;
padding: 8px 16px;
border-radius: 20px;
cursor: pointer;
z-index: 1000;
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
transition: all 0.3s ease;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.map-toggle-btn:hover {
background-color: rgba(0, 60, 120, 0.9);
border-color: rgba(255, 255, 255, 0.5);
}
/* 地图区域容器 */
.map-area-container {
position: relative;
width: 100%;
}
/* 地图内容容器 */
.map-content-container {
height: 500px;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<div style="height:100%;width:100%" :id="echartsId"></div>
<div class="bar-hat-chart" :id="echartsId"></div>
</template>
<script setup>
@ -35,6 +35,19 @@ const props = defineProps({
pauseOnHover: {
type: Boolean,
default: true
},
// 新增是否将X轴设为数据轴Y轴设为类别轴
isXAxisData: {
type: Boolean,
default: false
},
// 新增:自定义图表左边距
chartLeft: {
type: Object,
default: () => ({
dataAxis: "25%", // isXAxisData为true时的默认值
categoryAxis: "6%" // isXAxisData为false时的默认值
})
}
});
@ -174,38 +187,97 @@ function resumeAutoTooltip() {
// 处理数据
function handleDate() {
let xDate = props.data.xDate;
let categories = props.data.xDate;
let legend = props.data.list.map(v => { return { name: v.name } })
// 根据isXAxisData属性调整数据处理
let series = props.data.list.map((item, i) => {
let obj = {
name: item.name,
type: "bar",
data: item.value,
barWidth: "10px",
// 根据isXAxisData调整线性渐变方向
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: item.color ? item.color[0] : "rgba(0,244,255,1)" },
{ offset: 1, color: item.color ? item.color[1] : "rgba(0,77,167,1)" }], false),
color: new echarts.graphic.LinearGradient(
0, 0,
props.isXAxisData ? 1 : 0,
props.isXAxisData ? 0 : 1, [
{ offset: 0, color: item.color ? item.color[0] : "rgba(0,244,255,1)" },
{ offset: 1, color: item.color ? item.color[1] : "rgba(0,77,167,1)" }], false),
}
},
// 根据isXAxisData调整标记点位置
markPoint: {
symbol: 'path://M62 62h900v900h-900v-900z', // 使用 SVG path 绘制扁圆形状
symbolSize: [11, 4], // 设置扁圆的宽
symbolSize: props.isXAxisData ? [4, 11] : [11, 4], // 根据方向调整扁圆的宽高
itemStyle: { color: item.hatColor || '#087df9' },// 圆盘颜色
data: item.value.map((obj, index) => ({
xAxis: index, // 对应柱子的横坐标
yAxis: obj + 0 // 柱子的值加上一些偏移量
xAxis: props.isXAxisData ? obj + 0 : index, // 对应柱子的横坐标
yAxis: props.isXAxisData ? index : obj + 0 // 柱子的值加上一些偏移量
}))
},
}
return obj
})
lineChartFn(xDate, legend, series)
lineChartFn(categories, legend, series)
}
function lineChartFn(xDate, legend, series) {
function lineChartFn(categories, legend, series) {
myChart.value = echarts.init(document.getElementById(props.echartsId));
// 根据isXAxisData属性调整坐标轴配置
const xAxisConfig = {
type: props.isXAxisData ? "value" : "category",
data: props.isXAxisData ? null : categories,
axisLine: {
lineStyle: {
color: "rgba(255,255,255,0.12)"
}
},
axisLabel: {
margin: 10,
color: "#e2e9ff",
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,0.12)"
}
}
};
const yAxisConfig = {
type: props.isXAxisData ? "category" : "value",
data: props.isXAxisData ? categories : null,
// name: '单位:万元',
axisLabel: {
formatter: "{value}",
color: "#e2e9ff"
},
axisLine: {
show: false,
lineStyle: {
color: "rgba(255,255,255,0.12)"
}
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,0.12)"
}
}
};
// 根据isXAxisData属性调整grid配置
const gridConfig = {
top: "15%",
right: props.isXAxisData ? "2%" : "2%",
left: props.isXAxisData ? props.chartLeft.dataAxis : props.chartLeft.categoryAxis,
bottom: props.isXAxisData ? "15%" : "22%"
};
var option = {
legend: {
type: "plain",
@ -228,8 +300,7 @@ function lineChartFn(xDate, legend, series) {
formatter: function (params) {
// 获取当前数据点的所有系列信息
const dataIndex = params.dataIndex;
const categoryName = params.name;
const categoryName = props.isXAxisData ? categories[dataIndex] : params.name;
let result = `<div style="margin-bottom: 8px; font-weight: bold; color: #00d4ff; font-size: 14px; border-bottom: 1px solid #00d4ff; padding-bottom: 4px;">${categoryName}</div>`;
// 遍历所有系列,显示该数据点的所有信息
if (props.data && props.data.list) {
@ -253,7 +324,6 @@ function lineChartFn(xDate, legend, series) {
transitionDuration: 0.2,
// 设置提示框位置
position: function (point, params, dom, rect, size) {
// console.log(point, params, dom, rect, size);
// 设置提示框的z-index为999确保显示在最上层
dom.style.zIndex = 999;
@ -274,50 +344,9 @@ function lineChartFn(xDate, legend, series) {
return [x, y];
}
},
grid: {
top: "25%",
right: "2%",
left: "6%",
bottom: "22%"
},
xAxis: [
{
type: "category",
data: xDate,
axisLine: {
lineStyle: {
color: "rgba(255,255,255,0.12)"
}
},
axisLabel: {
margin: 10,
color: "#e2e9ff",
textStyle: {
fontSize: 14
}
}
}
],
yAxis: [
{
// name: '单位:万元',
axisLabel: {
formatter: "{value}",
color: "#e2e9ff"
},
axisLine: {
show: false,
lineStyle: {
color: "rgba(255,255,255,1)"
}
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,0.12)"
}
}
}
],
grid: gridConfig,
xAxis: [xAxisConfig],
yAxis: [yAxisConfig],
series: series
};
@ -349,7 +378,10 @@ function lineChartFn(xDate, legend, series) {
}
onMounted(() => {
lineChartFn();
// 确保组件挂载后有数据才初始化图表
if (props.data && props.data.list && props.data.list.length > 0) {
handleDate();
}
});
// 组件卸载时清理定时器
@ -368,4 +400,9 @@ onUnmounted(() => {
background: rgba(0,29,75,0.6);
border-radius: 0 0 4px 4px;
}
.bar-hat-chart {
height: 100%;
width: 100%;
}
</style>

View File

@ -13,11 +13,10 @@
<QbsbCount></QbsbCount>
</div>
<div class="commom-aside">
<KeyPpersonneltypes />
<!-- <KeyPpersonneltypes /> -->
<Statistics/>
</div>
<div class="commom-aside" @mouseenter="mouseEnter" @mouseleave="mouseLeave"
style="position: relative; height: 100%; overflow: hidden;">
<!-- <GroupWarning /> -->
<div class="commom-aside" @mouseenter="mouseEnter" @mouseleave="mouseLeave" >
<div style="position: relative; height: 100%;">
<transition name="flip" mode="out-in">
<div :key="'qb'" v-if="reversalPushShow" class="flip-wrapper">
@ -28,7 +27,6 @@
</div>
</transition>
</div>
<!-- <QbfkCount></QbfkCount> -->
</div>
</div>
</div>
@ -37,8 +35,15 @@
<div class="commom-aside-big">
<Calendar />
</div>
<div class="commom-aside-big">
<Experience />
<div class="commom-aside-big" @mouseenter="mouseEnter" @mouseleave="mouseLeave">
<transition name="flip" mode="out-in">
<div :key="'qb'" v-if="reversalShow" class="flip-wrapper">
<Experience @reversalPush="reversal"></Experience>
</div>
<div :key="'text'" v-else class="flip-wrapper">
<KeyPpersonneltypes @reversalPush="reversal"></KeyPpersonneltypes>
</div>
</transition>
</div>
<div class="commom-aside-small">
<!-- <SituationAssessment /> -->
@ -116,7 +121,8 @@ import Judgment from './model/judgment.vue'
import { tbYjxxGetList } from '@/api/zdr.js'
import GeneralWindow from './model/generalWindow.vue'
import WebSoketClass from '@/utils/webSocket.js'
import {timeValidate} from '@/utils/tools.js'
import { timeValidate } from '@/utils/tools.js'
import Statistics from './model/statistics.vue'
// 导入音频播放器工具类
import audioPlayer from '@/utils/audioPlayer'
const webSoket = new WebSoketClass()
@ -143,7 +149,7 @@ const changeXzqh = (val, trg) => {
type: "FeatureCollection",
features: [feature]
},
color: '#cf1010',
color: 'rgba(209 112 65,1)',
fillColor: 'rgba(255, 255, 255,0)',
})
})
@ -164,7 +170,7 @@ const changeXzqh = (val, trg) => {
}
]
},
color: '#cf1010',
color: 'rgba(209 112 65,1)',
fillColor: 'rgba(255, 255, 255,0)',
})
}
@ -318,12 +324,18 @@ const getTbYjxxGetList = () => {
}
let timing = ref(true)
// 情报翻转
const reversalPushShow = ref(true)
const reversalPush = () => {
reversalPushShow.value = !reversalPushShow.value
// 移除clearInterval调用避免定时器被清除
}
// 论坛翻转
const reversalShow = ref(true)
const reversal= () => {
reversalShow.value = !reversalShow.value
// 移除clearInterval调用避免定时器被清除
}
// 鼠标移入
const mouseEnter = () => {
clearInterval(timing.value)
@ -335,6 +347,7 @@ const mouseLeave = () => {
// 设置为5秒自动切换更容易测试效果
timing.value = setInterval(() => {
reversalPush()
reversal()
}, 30000)
}
onUnmounted(() => {
@ -475,7 +488,8 @@ onUnmounted(() => {
.flip-wrapper {
position: relative;
width: 100%;
height: calc(100%/3 - 8px);
// height: calc(100%/3 - 8px);
height: 100%;
backface-visibility: hidden;
perspective: 1000px;
}

View File

@ -1,38 +1,39 @@
<template>
<div class="comom-title">
<div class="title">预警处置统计</div>
<div class="title">预警处置统计</div>
</div>
<div class="comom-cnt" style="border-right: 1px solid #ebebeb;width: 100%;" v-loading="list.YjczDate.loading">
<BarHatEcharts echartsId="qylxEcharts" :data="list.YjczDate" :autoTooltip="true"></BarHatEcharts>
<BarHatEcharts echartsId="qylxEcharts" :data="list.YjczDate" :autoTooltip="true"></BarHatEcharts>
</div>
</template>
<script setup>
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import BarHatEcharts from "@/views/home/echarts/barHatEcharts.vue";
import { onMounted,reactive } from "vue";
import { onMounted, reactive } from "vue";
const list = reactive({
YjczDate: {
loading: false,
xDate: [],
list: [],
},
});
const getYjczDate = () => {
list.YjczDate.loading = true;
list.YjczDate.loading = true;
qcckGet({}, '/mosty-gsxt/tbYjxx/getYjCzztTj').then(res => {
list.YjczDate.loading = false;
list.YjczDate.xDate = res.map(item => item.zdmc);
list.YjczDate.list = [{ name:'总数',
value: res.map(item => item.count),
color: ['rgba(0,244,255,1)', 'rgba(0,77,167,1)'],
hatColor: '#087df9'
}]
list.YjczDate.list = [
{
name: '总数',
value: res.map(item => item.count),
color: ['rgba(0,244,255,1)', 'rgba(0,77,167,1)'],
hatColor: '#087df9'
}]
})
};
onMounted(() => {
getYjczDate()
getYjczDate()
});
// const tabHeightFn = () => {
@ -47,29 +48,32 @@ getYjczDate()
<style lang="scss" scoped>
@import "@/assets/css/homeScreen.scss";
::v-deeep .comom-title{
background: url("~@/assets/images/bg18.png") no-repeat center center;
background-size: 100% 100%;
}
::v-deeep .comom-cnt{
::v-deeep .comom-title {
background: url("~@/assets/images/bg18.png") no-repeat center center;
background-size: 100% 100%;
}
::v-deep .el-table td.el-table__cell{
::v-deeep .comom-cnt {
background: url("~@/assets/images/bg18.png") no-repeat center center;
background-size: 100% 100%;
}
::v-deep .el-table td.el-table__cell {
color: #ffffff;
}
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell{
background: rgba(0,61,130,0.75);
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell {
background: rgba(0, 61, 130, 0.75);
}
</style>
<style lang="scss">
.zdy_bkcz_table td.el-table__cell {
color: #ffffff !important;
color: #ffffff !important;
}
.zdy_bkcz_table th.el-table__cell {
color: #ffffff !important;
font-size: 15px;
color: #ffffff !important;
font-size: 15px;
}
</style>

View File

@ -28,7 +28,7 @@
<script setup>
import emitter from "@/utils/eventBus.js";
// import { qcckPost } from "@/api/qcckApi.js";
import { getPageAllList, yjzxXwyjId, tbYjxxGetInfo } from '@/api/yj.js'
import { getPageAllList, yjzxXwyjId, tbYjxxGetInfo,yjzxyjzxSfyjSelectList,yjzxZhyjSelectList } from '@/api/yj.js'
import DeployControlItem from "@/views/home/components/deployControlItem.vue";
import * as MOSTY from "@/components/MyComponents/index";
import CheckBox from "@/components/checkBox/index.vue";
@ -205,7 +205,10 @@ const content = ref({
hplx: null
})
const chooseItem = (item) => {
console.log(item.yjlx);
switch (item.yjlx) {
case '01':
tbYjxxGetInfo(item.id).then(res => {
content.value = {
@ -240,12 +243,15 @@ const chooseItem = (item) => {
yjlb: item.yjlb || '',
czzt: res.czzt || '',
yjbt: res.yjBt || '',
yjlx:item.yjlx
}
emitter.emit('showHomeYJ', [content.value]);
})
break;
case '03':
content.value = {
yjzxyjzxSfyjSelectList(item.id).then(res => {
content.value = {
id: item.id,
ryxm: res.xm || '',
rysfzh: res.sfzh,
@ -255,12 +261,15 @@ const chooseItem = (item) => {
yjbq: res.xwms || '',
yjlb: item.yjlb || '',
czzt: res.czzt || '',
yjbt: res.yjBt || '',
yjbt: res.yjBt || '',
yjlx:item.yjlx
}
emitter.emit('showHomeYJ', [content.value]);
})
break;
case '04':
content.value = {
yjzxZhyjSelectList(item.id).then(res => {
content.value = {
id: item.id,
ryxm: res.xm || '',
rysfzh: res.sfzh,
@ -270,9 +279,11 @@ const chooseItem = (item) => {
yjbq: res.xwms || '',
yjlb: item.yjlb || '',
czzt: res.czzt || '',
yjbt: res.yjBt || '',
yjbt: res.yjBt || '',
yjlx:item.yjlx
}
emitter.emit('showHomeYJ', [content.value]);
})
break;
}

View File

@ -1,6 +1,7 @@
<template>
<div class="comom-title" @click="chooseForumPost">
<span class="title">情报论坛</span>
<!-- <span class="title">情报论坛</span> -->
<div class="title">情报论坛<span class="switchover" @click.stop="reversalPush">切换</span></div>
</div>
<div class="comom-cnt" >
<div class="zdryBox">
@ -25,7 +26,10 @@ import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
import {useRouter} from 'vue-router'
import * as MOSTY from "@/components/MyComponents/index";
const router = useRouter()
const emit = defineEmits(["reversalPush"])
const reversalPush = () => {
emit('reversalPush')
}
// 数据相关
const personList = ref([]);
const loading = ref(false);
@ -206,4 +210,10 @@ onBeforeUnmount(() => {
}
}
}
.switchover{
cursor: pointer;
font-size: 14px;
margin-left: 20px;
color: rgb(255, 146, 4);
}
</style>

View File

@ -1,22 +1,26 @@
<template>
<div class="comom-title">
<span class="title">战术战略研判</span>
</div>
<div class="comom-cnt zdryBox">
<div class="model-box">
<div class="model-commom" style="" v-for="value in judgmentList" :key="value.title">
<img :src="value.img" alt="">
<div class="fontStlye">
<div class="font-bold" :style="{color: value.color}">{{value.title}}</div>
<div>{{value.num}}</div>
</div>
</div>
<div>
<span class="title" @click="reversalShow = true" :class="{ 'switchover': reversalShow }">战术研判</span>
<span class="title" @click="reversalShow = false" :class="{ 'switchover': !reversalShow }">战略研判</span>
</div>
</div>
<!-- <div class="comom-cnt zdryBox"> -->
<transition name="flip" mode="out-in">
<div :key="'qb'" v-if="reversalShow" class="flip-wrapper">
<TacticalYp></TacticalYp>
</div>
<div :key="'text'" v-else class="flip-wrapper">
<StrategyYp></StrategyYp>
</div>
</transition>
<!-- </div> -->
</template>
<script setup>
import { ref, onMounted } from 'vue';
import TacticalYp from './tacticalYp.vue'
import StrategyYp from './strategyYp.vue'
const judgmentList = ref([
{
title: '战略研判数',
@ -28,24 +32,22 @@ const judgmentList = ref([
title: '战术研判数',
num: 12,
img: require('@/assets/images/y2.png'),
color: '#e5d923'
color: '#e5d923'
},
{
title: '战术会商数',
num: 24,
img: require('@/assets/images/y3.png'),
color: '#e56723'
color: '#e56723'
},
{
title: '战略会商数',
num: 30,
img: require('@/assets/images/y4.png') ,
color: '#77e523'
img: require('@/assets/images/y4.png'),
color: '#77e523'
}
])
const reversalShow = ref(true)
</script>
@ -119,23 +121,70 @@ const judgmentList = ref([
::v-deep .el-checkbox__input.is-indeterminate .el-checkbox__inner::before {
background: #000;
}
.model-box{
display: flex;justify-content: space-between;padding: 20px;flex-wrap: wrap;
.model-box {
display: flex;
justify-content: space-between;
padding: 20px;
flex-wrap: wrap;
}
.model-commom {
width: 50%;
border-radius: 5px;
height: 100px;
position: relative;
.fontStlye{
.fontStlye {
font-size: 20px;
font-weight: 500;
position: absolute;z-index: 20;top: 18px;left: 80px;
.font-bold{
margin-bottom: 10px;
font-family: "YSBTH";
}
font-weight: 500;
position: absolute;
z-index: 20;
top: 18px;
left: 80px;
.font-bold {
margin-bottom: 10px;
font-family: "YSBTH";
}
}
}
.switchover {
cursor: pointer;
font-size: 14px;
color: rgb(255, 146, 4);
}
/* 包装层样式 */
.flip-wrapper {
position: relative;
width: 100%;
// height: calc(100%/3 - 8px);
height: 100%;
backface-visibility: hidden;
perspective: 1000px;
}
/* 翻转过渡动画 */
.flip-enter-active,
.flip-leave-active {
transition: all 0.6s ease;
transform-style: preserve-3d;
}
.flip-enter-from {
transform: rotateX(90deg);
opacity: 0;
}
.flip-leave-to {
transform: rotateX(-90deg);
opacity: 0;
}
.flip-enter-to,
.flip-leave-from {
transform: rotateX(0deg);
opacity: 1;
}
</style>

View File

@ -1,6 +1,7 @@
<template>
<div class="comom-title">
<span class="title">重点人员类型</span>
<!-- <span class="title">重点人员类型</span> -->
<div class="title">重点人员类型<span class="switchover" @click.stop="reversalPush">切换</span></div>
<div class="title titleFz" style="" @click="visible = true">
查看列表
</div>
@ -26,6 +27,10 @@ const data = ref([
{ value: 30, name: '重点上访人员' },
{ value: 30, name: '僧尼人员' },
])
const emit = defineEmits(["reversalPush"])
const reversalPush = () => {
emit('reversalPush')
}
const visible = ref(false)
const tbGsxtZdryzdryBqtjFn = () => {
tbGsxtZdryzdryBqtj({ bqlx: '01' }).then(res => {
@ -56,4 +61,10 @@ tbGsxtZdryzdryBqtjFn()
font-size: 14px !important;
color: rgb(255, 166, 14);
}
.switchover{
cursor: pointer;
font-size: 14px;
margin-left: 20px;
color: rgb(255, 146, 4);
}
</style>

View File

@ -29,7 +29,7 @@ const list = reactive({
xDate: ['110警情', '人力情报', '系统采集', '民警处置单'],
list: [
{ name: "总数", value: [0, 0, 0, 0,], color: ['rgba(0,244,255,1)', 'rgba(0,77,167,1)'], hatColor: '#087df9' },
{ name: "已处置", value: [0, 0, 0, 0], color: ['rgba(24, 232, 229, 1)', 'rgba(3, 110, 83, 1)'], hatColor: '#00FFFF' },
// { name: "已处置", value: [0, 0, 0, 0], color: ['rgba(24, 232, 229, 1)', 'rgba(3, 110, 83, 1)'], hatColor: '#00FFFF' },
],
})
const emit = defineEmits(['reversalPush'])
@ -43,11 +43,18 @@ const getCount = () => {
startTime: listQuery.value?.startTime || "",
endTime: listQuery.value?.endTime || ""
}
qcckPost(promes, '/mosty-gsxt/qbcj/getXscjTjForLylx').then(res => {
list.xDate = res ? res.cz.map(v => v.zdmc) : [];
list.list[0].value = res ? res.zs.map(v => v.count) : [];
list.list[1].value = res ? res.cz.map(v => v.count) : [];
// qcckPost(promes, '/mosty-gsxt/qbcj/getXscjTjForLylx').then(res => {
// list.xDate = res ? res.cz.map(v => v.zdmc) : [];
// list.list[0].value = res ? res.zs.map(v => v.count) : [];
// list.list[1].value = res ? res.cz.map(v => v.count) : [];
// })
qcckPost(promes, '/mosty-gsxt/qbcj/sjlyCount').then(res => {
list.xDate = res ? res.map(v => v.zdmc) : [];
list.list[0].value = res ? res.map(v => v.count) : [];
})
}
const changeTime = (val) => {
listQuery.value = {
@ -56,7 +63,6 @@ const changeTime = (val) => {
getCount()
}
const reversalPush = () => {
emit('reversalPush')
}
const close = () => {

View File

@ -0,0 +1,254 @@
<template>
<div class="comom-cnt chart-container" @mouseenter="mouseEnter" @mouseleave="mouseLeave">
<span class="toggle-btn" @click="addFn">切换</span>
<transition name="flip" mode="out-in">
<div v-if="list[add]" class="flip-wrapper chart-content" :key="add">
<BarHatEcharts :isXAxisData="true" :echartsId="`qylxEchartsmm-${add}`" :data="list[add]" :autoTooltip="true" :chartLeft="{ dataAxis:'25%', categoryAxis: '5%' }" />
</div>
<div v-else class="flip-wrapper no-data">
暂无数据
</div>
</transition>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, onUnmounted } from 'vue';
import { tbGsxtXscjTjForSjbm } from '@/api/qbcj'
import BarHatEcharts from "@/views/home/echarts/barHatEcharts.vue";
const list = ref([]);
// 请求数据
const getXscjTjForSjbm = () => {
tbGsxtXscjTjForSjbm({}).then(res => {
// 先将原始数据处理为一维数组
const zsDataArray = res.zs.map((item, index) => {
return {
org_name: item.org_name,
zsCount: item.count,
yczCount: item.org_name === res.ycz[index].org_name ? res.ycz[index].count : 0
}
});
// 将一维数组转换为每7个元素为一组的二维数组
const groupSize = 7;
const ZsData = Array.from({
length: Math.ceil(zsDataArray.length / groupSize)
}, (_, i) => zsDataArray.slice(i * groupSize, (i + 1) * groupSize));
console.log(ZsData);
list.value = ZsData.map(item => {
return {
loading: false,
list: [{
name: '总数',
value: item.map(items => items.zsCount),
color: ['rgba(0,244,255,1)', 'rgba(0,77,167,1)'],
}, {
name: '已处置',
value: item.map(items => items.yczCount),
color: ['rgba(24, 232, 229, 1)', 'rgba(3, 110, 83, 1)'],
}],
xDate: item.map(item => {
if (item.org_name.indexOf('林芝市公安局') == 0) {
return item.org_name.slice(6, item.org_name.length)
} else if (item.org_name.indexOf('林芝市') == 0) {
return item.org_name.slice(3, item.org_name.length)
} else if (item.org_name.indexOf('西藏自治区林芝市') == 0) {
return item.org_name.slice(8, item.org_name.length)
} else {
return item.org_name
}
})
}
})
})
}
const add = ref(0)
const addFn = () => {
// 确保list数组有数据时才执行切换操作
if (list.value.length > 0) {
// 确保不超过list的长度实现循环切换
add.value = (add.value + 1) % list.value.length
}
}
let times=ref()
onMounted(() => {
getXscjTjForSjbm()
times.value=setInterval(() => {
addFn()
}, 30000);
// getYjczDate()
})
// 鼠标移入
const mouseEnter = () => {
clearInterval(times.value)
}
// 鼠标移出
const mouseLeave = () => {
// 清除可能存在的旧定时器,避免多个定时器同时运行
clearInterval(times.value)
// 设置为5秒自动切换更容易测试效果
times.value = setInterval(() => {
addFn()
}, 30000)
}
onUnmounted(() => {
clearInterval(times.value)
})
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5);
}
</style>
<style lang="scss" scoped>
@import "@/assets/css/homeScreen.scss";
.loading-more {
text-align: center;
padding: 8px;
color: #83bff6;
background: rgba(0, 0, 0, 0.3);
font-size: 12px;
}
.zdryBox {
height: 100%;
position: relative;
overflow: hidden;
.ryBox {
height: 100%;
overflow-y: auto;
margin: 0;
padding: 0;
list-style: none;
// 隐藏滚动条但保留滚动功能
&::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none; // IE和Edge
scrollbar-width: none; // Firefox
li {
padding: 12px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
transition: background-color 0.3s;
cursor: pointer;
box-sizing: border-box;
&:hover {
background-color: rgba(20, 107, 190, 0.2);
}
>div:first-child {
font-weight: bold;
color: #fff;
margin-bottom: 8px;
font-size: 14px;
/* 标题限制1行超出用省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.meta-info {
text-align: right;
color: #83bff6;
font-size: 12px;
margin-bottom: 8px;
}
>div:last-child {
color: rgba(255, 255, 255, 0.8);
font-size: 13px;
line-height: 1.6;
/* 内容限制3行超出用省略号 */
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.switchover {
cursor: pointer;
font-size: 14px;
margin-left: 20px;
color: rgb(255, 146, 4);
}
/* 图表容器样式 */
.chart-container {
border-right: 1px solid #ebebeb;
width: 100%;
height: 100% !important;
}
/* 切换按钮样式 */
.toggle-btn {
position: absolute;
z-index: 10;
cursor: pointer;
font-size: 14px;
margin-left: 20px;
color: rgb(255, 146, 4);
font-family: 'YSBTH';
}
/* 图表内容区域样式 */
.chart-content {
height: 100%;
}
/* 暂无数据样式 */
.no-data {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
}
// 翻转过渡动画样式
.flip-wrapper {
position: relative;
width: 100%;
height: 100%;
perspective: 1000px;
}
.flip-enter-active,
.flip-leave-active {
transition: all 0.6s ease;
transform-style: preserve-3d;
}
.flip-enter-from {
transform: rotateY(90deg);
opacity: 0;
}
.flip-enter-to {
transform: rotateY(0deg);
opacity: 1;
}
.flip-leave-from {
transform: rotateY(0deg);
opacity: 1;
}
.flip-leave-to {
transform: rotateY(-90deg);
opacity: 0;
}
</style>

View File

@ -0,0 +1,216 @@
<template>
<div class="comom-cnt" >
<div class="zdryBox">
<ul class="ryBox" :infinite-scroll-distance="30" ref="carouselList" @mouseenter="stopAutoScroll" @mouseleave="startAutoScroll"
v-loading="loading" v-infinite-scroll="loadList">
<li v-for="item in personList" :key="item.id" @click="chooseItem(item)">
<div>{{ item.title }}</div>
<div class="meta-info">{{ item.time }}{{ item.fbrxm }}</div>
<div>{{ item.content }}</div>
</li>
<MOSTY.Empty :show="!loading && personList.length <= 0" :imgSize="100"></MOSTY.Empty>
</ul>
<!-- 触底加载更多数据 -->
<div v-if="loadingMore" class="loading-more">加载中...</div>
</div>
</div>
</template>
<script setup>
import { tbGsxtXxltSelectPage } from '@/api/tbGsxtXxltHf'
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
import {useRouter} from 'vue-router'
import * as MOSTY from "@/components/MyComponents/index";
const router = useRouter()
const emit = defineEmits(["reversalPush"])
const reversalPush = () => {
emit('reversalPush')
}
// 数据相关
const personList = ref([]);
const loading = ref(false);
const loadingMore = ref(false);
const total = ref(0);
const pageNum = ref(1);
// 滚动相关
const carouselList = ref(null);
const isAutoScrolling = ref(false);
let scrollTimer = null;
// 获取数据
const getList = (type) => {
loading.value = !type ? true : false;
loadingMore.value = !!type;
tbGsxtXxltSelectPage({ pageSize: 10, pageCurrent: pageNum.value }).then(res => {
loading.value = false;
loadingMore.value = false;
let arr = res.records || [];
personList.value = pageNum.value == 1 ? arr : personList.value.concat(arr);
total.value = res.total;
}).catch(() => {
loading.value = false;
loadingMore.value = false;
})
};
// 触底加载
const loadList = () => {
if (personList.value.length == total.value || loadingMore.value) return;
pageNum.value++;
getList(true)
};
// 自动滚动函数
const autoScroll = () => {
if (!carouselList.value || !isAutoScrolling.value) return;
const container = carouselList.value;
const speed = 1; // 滚动速度
// 滚动容器
container.scrollTop += speed;
// 判断是否滚动到底部,如果是则回到顶部重新开始
if (container.scrollTop >= container.scrollHeight - container.clientHeight - 5) {
container.scrollTop = 0;
}
};
// 开始自动滚动
const startAutoScroll = () => {
if (isAutoScrolling.value || !carouselList.value) return;
isAutoScrolling.value = true;
// 清除可能存在的定时器
if (scrollTimer) {
clearInterval(scrollTimer);
}
// 设置新的定时器,控制滚动速度
scrollTimer = setInterval(autoScroll, 30);
};
// 停止自动滚动
const stopAutoScroll = () => {
isAutoScrolling.value = false;
if (scrollTimer) {
clearInterval(scrollTimer);
scrollTimer = null;
}
};
// 点击项
const chooseItem = (item) => {
stopAutoScroll(); // 点击时停止自动滚动
router.push({
path: '/forumPost',
query: { id: item.id }
})
};
// 添加跳转
const chooseForumPost = () => {
stopAutoScroll(); // 点击时停止自动滚动
router.push({ path: '/forumPost' })
};
// 生命周期
onMounted(() => {
getList();
// 数据加载完成后启动自动滚动
setTimeout(() => {
if (personList.value.length > 0) {
startAutoScroll();
}
}, 1000);
});
// 组件卸载前清除定时器
onBeforeUnmount(() => {
stopAutoScroll();
});
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5);
}
</style>
<style lang="scss" scoped>
@import "@/assets/css/homeScreen.scss";
.loading-more {
text-align: center;
padding: 8px;
color: #83bff6;
background: rgba(0, 0, 0, 0.3);
font-size: 12px;
}
.zdryBox {
height: 100%;
position: relative;
overflow: hidden;
.ryBox {
height: 100%;
overflow-y: auto;
margin: 0;
padding: 0;
list-style: none;
// 隐藏滚动条但保留滚动功能
&::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none; // IE和Edge
scrollbar-width: none; // Firefox
li {
padding: 12px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
transition: background-color 0.3s;
cursor: pointer;
box-sizing: border-box;
&:hover {
background-color: rgba(20, 107, 190, 0.2);
}
> div:first-child {
font-weight: bold;
color: #fff;
margin-bottom: 8px;
font-size: 14px;
/* 标题限制1行超出用省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.meta-info {
text-align: right;
color: #83bff6;
font-size: 12px;
margin-bottom: 8px;
}
> div:last-child {
color: rgba(255, 255, 255, 0.8);
font-size: 13px;
line-height: 1.6;
/* 内容限制3行超出用省略号 */
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.switchover{
cursor: pointer;
font-size: 14px;
margin-left: 20px;
color: rgb(255, 146, 4);
}
</style>

View File

@ -0,0 +1,215 @@
<template>
<div class="comom-cnt" >
<div class="zdryBox">
<ul class="ryBox" :infinite-scroll-distance="30" ref="carouselList" @mouseenter="stopAutoScroll" @mouseleave="startAutoScroll"
v-loading="loading" v-infinite-scroll="loadList">
<li v-for="item in personList" :key="item.id" @click="chooseItem(item)">
<div>{{ item.title }}</div>
<div class="meta-info">{{ item.time }}{{ item.fbrxm }}</div>
<div>{{ item.content }}</div>
</li>
<MOSTY.Empty :show="!loading && personList.length <= 0" :imgSize="100"></MOSTY.Empty>
</ul>
<!-- 触底加载更多数据 -->
<div v-if="loadingMore" class="loading-more">加载中...</div>
</div>
</div>
</template>
<script setup>
import { tbGsxtXxltSelectPage } from '@/api/tbGsxtXxltHf'
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
import {useRouter} from 'vue-router'
import * as MOSTY from "@/components/MyComponents/index";
const router = useRouter()
const emit = defineEmits(["reversalPush"])
const reversalPush = () => {
emit('reversalPush')
}
// 数据相关
const personList = ref([]);
const loading = ref(false);
const loadingMore = ref(false);
const total = ref(0);
const pageNum = ref(1);
// 滚动相关
const carouselList = ref(null);
const isAutoScrolling = ref(false);
let scrollTimer = null;
// 获取数据
const getList = (type) => {
loading.value = !type ? true : false;
loadingMore.value = !!type;
tbGsxtXxltSelectPage({ pageSize: 10, pageCurrent: pageNum.value }).then(res => {
loading.value = false;
loadingMore.value = false;
let arr = res.records || [];
personList.value = pageNum.value == 1 ? arr : personList.value.concat(arr);
total.value = res.total;
}).catch(() => {
loading.value = false;
loadingMore.value = false;
})
};
// 触底加载
const loadList = () => {
if (personList.value.length == total.value || loadingMore.value) return;
pageNum.value++;
getList(true)
};
// 自动滚动函数
const autoScroll = () => {
if (!carouselList.value || !isAutoScrolling.value) return;
const container = carouselList.value;
const speed = 1; // 滚动速度
// 滚动容器
container.scrollTop += speed;
// 判断是否滚动到底部,如果是则回到顶部重新开始
if (container.scrollTop >= container.scrollHeight - container.clientHeight - 5) {
container.scrollTop = 0;
}
};
// 开始自动滚动
const startAutoScroll = () => {
if (isAutoScrolling.value || !carouselList.value) return;
isAutoScrolling.value = true;
// 清除可能存在的定时器
if (scrollTimer) {
clearInterval(scrollTimer);
}
// 设置新的定时器,控制滚动速度
scrollTimer = setInterval(autoScroll, 30);
};
// 停止自动滚动
const stopAutoScroll = () => {
isAutoScrolling.value = false;
if (scrollTimer) {
clearInterval(scrollTimer);
scrollTimer = null;
}
};
// 点击项
const chooseItem = (item) => {
stopAutoScroll(); // 点击时停止自动滚动
router.push({
path: '/forumPost',
query: { id: item.id }
})
};
// 添加跳转
const chooseForumPost = () => {
stopAutoScroll(); // 点击时停止自动滚动
router.push({ path: '/forumPost' })
};
// 生命周期
onMounted(() => {
getList();
// 数据加载完成后启动自动滚动
setTimeout(() => {
if (personList.value.length > 0) {
startAutoScroll();
}
}, 1000);
});
// 组件卸载前清除定时器
onBeforeUnmount(() => {
stopAutoScroll();
});
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5);
}
</style>
<style lang="scss" scoped>
@import "@/assets/css/homeScreen.scss";
.loading-more {
text-align: center;
padding: 8px;
color: #83bff6;
background: rgba(0, 0, 0, 0.3);
font-size: 12px;
}
.zdryBox {
height: 100%;
position: relative;
overflow: hidden;
.ryBox {
height: 100%;
overflow-y: auto;
margin: 0;
padding: 0;
list-style: none;
// 隐藏滚动条但保留滚动功能
&::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none; // IE和Edge
scrollbar-width: none; // Firefox
li {
padding: 12px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
transition: background-color 0.3s;
cursor: pointer;
box-sizing: border-box;
&:hover {
background-color: rgba(20, 107, 190, 0.2);
}
> div:first-child {
font-weight: bold;
color: #fff;
margin-bottom: 8px;
font-size: 14px;
/* 标题限制1行超出用省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.meta-info {
text-align: right;
color: #83bff6;
font-size: 12px;
margin-bottom: 8px;
}
> div:last-child {
color: rgba(255, 255, 255, 0.8);
font-size: 13px;
line-height: 1.6;
/* 内容限制3行超出用省略号 */
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.switchover{
cursor: pointer;
font-size: 14px;
margin-left: 20px;
color: rgb(255, 146, 4);
}
</style>